代码如下:
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格式。
那么,有人可以告诉我为什么吗?几天来我一直在努力解决这个问题。
提前致谢。
答案 0 :(得分:9)
(->) String
has a Monad instance但这不是你想要的。当您在do
的定义中使用p
- 符号时,此实例就是被拾取的实例。
您要做的是为Monad
制作您自己的Parser
个实例(这需要将其从类型同义词更改为newtype
包装器String -> [(a, String)]
以上)然后让它在p
的定义中被选中。
请注意,您的示例代码已经具有return
(名称为retrn
)的实现,该实现正确,并且与return
的{{1}}非常不同{1}}是(->) String
。