我正在为解析器编写Monad实例,并且在尝试实现bind时遇到了一些类型检查错误。以下代码未键入check:
parse (f a) i
GHCi抱怨最后一行代码ParseResult b
期待ParseResult a
类型但收到类型f =<< p = P (\s -> let x = parse p s
in let (Result i a) = x
in parse (f a) i)
。但是,如果我删除错误检查代码,那么所有类型检查都很好:
import java.time.LocalDate
val now = LocalDate.now()
那么if-then-else表达式导致类型混淆的是什么呢?
答案 0 :(得分:12)
比较
data Boring a = Boring
doesn'tTypeCheck :: Boring a -> Boring b
doesn'tTypeCheck x = x
doesTypeCheck :: Boring a -> Boring b
doesTypeCheck Boring = Boring
您的情况类似:虽然您的错误结果x
可能实际上并未包含任何a
值,但其类型仍标有a
。你需要&#34;重拍&#34;它与b
。通过从if
切换到case
语句,这可能是最干净的,如
case parse p s of
Error e {- :: ParseResult a -} -> Error e {- :: ParseResult b -}
Result i a -> parse (f a) i