我想写一个specialization rewrite rule为Megaparsec组合器,以便仅在输入类型为ByteString
时才触发规则。
{-# LANGUAGE ExplicitForAll #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeFamilies #-} import Data.Void import Text.Megaparsec import qualified Data.ByteString as B combin :: forall e s m a. (MonadParsec e s m) => m a -> m a combin = label "String generic" combinByteString :: forall e s m a. (MonadParsec e s m, s ~ B.ByteString) => m a -> m a combinByteString = label "ByteString specialized" main = do parseTest (combin empty :: Parsec Void String String) "" parseTest (combin empty :: Parsec Void B.ByteString String) "" {-# NOINLINE combin #-} {-# NOINLINE combinByteString #-} {-# RULES "combin/ByteString" combin = combinByteString #-}
当我尝试构建它时失败:
$ cabal v2-run Build profile: -w ghc-8.6.5 -O1 Main.hs:25:40: error: • Couldn't match type ‘s’ with ‘B.ByteString’ arising from a functional dependency between constraints: ‘MonadParsec e B.ByteString m’ arising from a use of ‘combinByteString’ at Main.hs:25:40-55 ‘MonadParsec e s m’ arising from the RULE "combin/ByteString" at Main.hs:25:11-55 ‘s’ is a rigid type variable bound by the RULE "combin/ByteString" at Main.hs:25:11-55 • In the expression: combinByteString When checking the transformation rule "combin/ByteString" | 25 | {-# RULES "combin/ByteString" combin = combinByteString #-}
s
的输入流类型参数MonadParsec
在MonadParsec
参数functional dependency上具有Monad
。
m
这里是
class (Stream s, MonadPlus m) => MonadParsec e s m | m -> e s where
文件,用于尝试构建。
specialize.cabal
如果成功,输出应如下所示:
cabal-version: >=1.10 name: specialize version: 0.1.0.0 build-type: Simple executable specialize main-is: Main.hs build-depends: base >= 4 ,megaparsec ,bytestring default-language: Haskell2010
建议?
我想为Megaparsec组合器编写一个特殊化重写规则,以便仅在输入类型为ByteString时才触发该规则。 {-#语言ExplicitForAll#-} {-#语言...
此规则有效,但仅适用于GHC 8.8.1,不适用于GHC 8.6.5。