为什么我的haskell从"Functional Programming in Haskell"书上复制的代码无法成功解释?

Why my haskell code copying from the book "Functional Programming in Haskell" can't be successfully interpreted?

代码如下:

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格式。

所以,有人能告诉我为什么吗?我已经为这场斗争努力了好几天。

提前致谢。

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

您想要做的是为 Parser 创建您自己的 Monad 实例(这需要将其从类型同义词更改为 newtype 包装器 String -> [(a, String)])然后在 p.

的定义中获取它

请注意,您的示例代码已经有一个 return 的实现(以 retrn 的名义),它做了正确的事情,而且它与 return 的也有很大不同因为 (->) String 是(这将是 retrn v = \inp -> v.