Parsing Monad解析器-canned';t匹配预期类型‘;[(b,字符串)]&x2019;实际类型为‘;解析器b’;
我正在使用G.Hutton的“Haskell编程”学习Haskell。我正在学习一元语法分析器的第13章。 首先,我定义一个类型解析器: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
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
)