作为我正在编写的 mini-haskell 编译器的一部分,我有一个名为app
. 我想要这个函数做的是接受这些参数epp (App e1 e2)
。第一步是e1
递归地评估 ( epp e1
) 并检查输出是否是错误的。如果不是,则评估e2
然后调用另一个函数eppVals
来评估调用的输出e1
,e2
我分别定义为v1
和v2
。
问问题
180 次
1 回答
1
在您的 hpaste 中,您有一个appVals
已eppVals
在上面的问题中重命名为的函数。这是无益的。
让我们看一些类型:
epp :: Exp -> Error Val
appVals :: Val -> Val -> Error Val
错误消息Couldn't match expected type Val
with actual typeError Val
试图告诉您第一个参数应该appVals
具有类型(Val
请参阅类型签名appVals
),但您作为第一个参数提供的值的实际类型v1
是,定义为epp e1
,它具有类型Error Val
(参见 的类型签名epp
)。
Val
并且Error Val
不是同一类型。那是你的问题。
如何解决?您需要某种方法将错误情况与其余计算分开处理。如果您已经为您的类型实现了Applicative
or类,那么几乎可以肯定这就是他们所做的。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)
现在你可以重写
epp (App e1 e2) = eppVals <$> epp e1 <*> epp e2
于 2012-11-17T10:56:14.337 回答