我正在为解析器编写Monad实例,但在尝试实现bind时遇到了一些类型检查错误。以下代码未通过类型检查:
那么,是什么导致if-then-else表达式引起类型混淆呢?
(=<<) :: (a -> Parser b) -> Parser a -> Parser b
f =<< p = P (\s -> let x = parse p s
in if isErrorResult x
then x
else let (Result i a) = x
in parse (f a) i)
GHCi报错称最后一行代码parse (f a) i
期望类型为ParseResult b
但实际接收到的类型是ParseResult a
。然而,如果我删除错误检查代码,那么所有类型检查都能够正常通过:
f =<< p = P (\s -> let x = parse p s
in let (Result i a) = x
in parse (f a) i)
那么,是什么导致if-then-else表达式引起类型混淆呢?
a
。因此,在第一个版本中,绑定可以返回ParseResult a
(在then x
中)或者从parse (f a) i
中返回ParseResult b
(来自parse (f a) i
)。 - bartop