作为我正在编写的mini-haskell编译器的一部分,我有一个名为app
的函数。我希望这个函数做的是接受这些参数epp (App e1 e2)
。第一步是递归地评估e1
(epp e1
)并检查输出是否是错误。如果没有,请评估e2
,然后调用另一个函数eppVals
来评估e1
和e2
上的调用输出,我将其定义为v1
和{{ 1}}分别。
答案 0 :(得分:1)
在您的hpaste中,您的功能appVals
已在上述问题中重命名为eppVals
。这是无益的。
让我们看看一些类型:
epp :: Exp -> Error Val
appVals :: Val -> Val -> Error Val
错误消息无法匹配预期类型Val
与实际类型Error Val
正试图告诉您appVals
的第一个参数是期望具有类型Val
(请参阅appVals
的类型签名),但您作为第一个参数提供的值的实际类型是{{ 1}},定义为v1
,其类型为epp e1
(请参阅Error Val
的类型签名)。
epp
和Val
的类型不同。那是你的问题。
如何解决?您需要一些与其余计算分开处理错误情况的方法。如果您已为Error Val
类型实施了Applicative
或Monad
类,那么这几乎肯定是他们所做的。
修改:您没有包含Error
的定义,但我希望它看起来像这样:
Error
为它实现几个类(您需要data Error a = S a | Error String
):
import Control.Applicative
现在你可以重写
instance Functor Error where
fmap f (S x) = S (f x)
fmap _ (Error s) = Error s
instance Applicative Error where
pure = S
Error s <*> _ = Error s
_ <*> Error s = Error s
S f <*> S x = S (f x)