Parsing Monad解析器-canned';t匹配预期类型‘;[(b,字符串)]&x2019;实际类型为‘;解析器b’;

Parsing Monad解析器-canned';t匹配预期类型‘;[(b,字符串)]&x2019;实际类型为‘;解析器b’;,parsing,haskell,types,functional-programming,monads,Parsing,Haskell,Types,Functional Programming,Monads,我正在使用G.Hutton的“Haskell编程”学习Haskell。我正在学习一元语法分析器的第13章。 首先,我定义一个类型解析器: newtype Parser a = P (String -> [(a, String)]) 然后是一个解析函数 parse:: Parser a -> String -> [(a, String)] 我将解析器设为单子 instance Monad Parser where --return :: a -> Parser a r

我正在使用G.Hutton的“Haskell编程”学习Haskell。我正在学习一元语法分析器的第13章。 首先,我定义一个类型解析器:

newtype Parser a = P (String -> [(a, String)])
然后是一个解析函数

parse:: Parser a -> String -> [(a, String)]
我将解析器设为单子

instance Monad Parser where
--return :: a -> Parser a
 return v =  P(\inp -> [(v, inp)])

--(>>=) :: Parser a -> (a -> Parser b) -> Parser b
 p >>=  g = P (\inp -> case parse p inp of
  [] -> []
  [(v, out)] -> parse (g v) out)
我的问题在Monad实例的最后一行 为什么会这样

而不是这个

[(v, out)] -> (g v))

>=
返回解析器b,而不是
[(b,String)]
。实际上
gv
,是一个解析器


我知道我错了,但我不明白为什么。

>=
返回一个解析器b,而不是[(b,字符串)]。实际上
gv
,是一个
解析器

这是正确的,但是我们正在构造一个具有外部
p
解析器。事实上:

p >>=  g = P (\inp -> case parse p inp of
  [] -> []
  [(v, out)] -> parse (g v) out)
或者我们可以使用为列表定义的绑定运算符
>=

p >>= g = P (
    \inp -> parse p inp >>= \(v, out) -> parse (g v) out
  )

您将它包装在
P
构造函数中,因此它的类型应该是
String->[(a,String)]
。这就是说,解析器还没有完成,因为列表可能包含多个元素。
p >>= g = P (
    \inp -> concatMap (\(v, out) -> parse (g v) out) (parse p inp)
  )
p >>= g = P (
    \inp -> parse p inp >>= \(v, out) -> parse (g v) out
  )