为什么我从“Haskell中的函数编程”一书中复制的haskell代码无法成功解释?

时间:2015-12-02 05:24:58

标签: haskell monads

代码如下:

type Parser a = String -> [(a, String)]

retrn :: a -> Parser a
retrn v = \inp -> [(v, inp)]

parse :: Parser a -> String -> [(a, String)]
parse p inp = p inp

item :: Parser Char
item = \inp -> case inp of
        []        -> []
        (x:xs)    -> [(x, xs)]

--problem code
p :: Parser (Char, Char)
p = do x <- item
       item
       y <- item
       retrn (x, y)

它会出现以下类型错误:

SO-34035520.hs:19:8:
    Couldn't match type `[(Char, String)]' with `Char'
    Expected type: String -> [((Char, Char), String)]
      Actual type: Parser ([(Char, String)], [(Char, String)])
    In a stmt of a 'do' block: retrn (x, y)
    In the expression:
      do { x <- item;
           item;
           y <- item;
           retrn (x, y) }

值得注意的是,本书官方网站上的示例代码可以顺利解释,即* .lhs格式。

那么,有人可以告诉我为什么吗?几天来我一直在努力解决这个问题。

提前致谢。

1 个答案:

答案 0 :(得分:9)

(->) String has a Monad instance但这不是你想要的。当您在do的定义中使用p - 符号时,此实例就是被拾取的实例。

您要做的是为Monad制作您自己的Parser个实例(这需要将其从类型同义词更改为newtype包装器String -> [(a, String)]以上)然后让它在p的定义中被选中。

请注意,您的示例代码已经具有return(名称为retrn)的实现,该实现正确,并且与return的{​​{1}}非常不同{1}}是(->) String