Haskell中为Parser实现HuttonMonad实例时遇类型错误的解决方法
解决Hutton解析器Monad实例的编译错误
你遇到的编译错误核心原因是:用type定义的Parser是类型同义词,现代GHC不允许直接为类型同义词定义类型类实例——只有newtype或data定义的真正类型构造器才能作为类型类实例的参数。
按照论文逻辑,只需把type改成newtype并做少量包装适配即可,完整代码如下:
class HuttonMonad m where result :: a -> m a bind :: m a -> (a -> m b) -> m b -- 用newtype替代type,将Parser转为真正的类型构造器 newtype Parser a = Parser { runParser :: String -> [(a, String)] } instance HuttonMonad Parser where result v = Parser $ \input -> [(v, input)] bind p f = Parser $ \inp -> concat [ runParser (f v) out | (v, out) <- runParser p inp ]
修改说明
newtype是零开销的类型包装,Haskell编译器会自动优化掉包装层,不影响性能- 用
Parser构造器把解析函数包装成Parser类型,用runParser取出内部函数进行逻辑处理 - 核心的
result和bind逻辑完全和论文一致,仅适配了现代GHC的类型系统规则
如果非要保留type定义,可以在文件开头添加{-# LANGUAGE TypeSynonymInstances #-}开启扩展,但这种方式不推荐——newtype更符合Haskell类型规范,也能避免扩展带来的潜在问题。
内容的提问来源于stack exchange,提问作者wirrbel
相关产品推荐
相关产品推荐

