0

作为我正在编写的 mini-haskell 编译器的一部分,我有一个名为app. 我想要这个函数做的是接受这些参数epp (App e1 e2)。第一步是e1递归地评估 ( epp e1) 并检查输出是否是错误的。如果不是,则评估e2然后调用另一个函数eppVals来评估调用的输出e1e2我分别定义为v1v2

4

1 回答 1

1

在您的 hpaste 中,您有一个appValseppVals在上面的问题中重命名为的函数。这是无益的。

让我们看一些类型:

  • epp :: Exp -> Error Val
  • appVals :: Val -> Val -> Error Val

错误消息Couldn't match expected type Valwith actual typeError Val试图告诉您第一个参数应该appVals具有类型Val请参阅类型签名appVals),但您作为第一个参数提供的值的实际类型v1是,定义为epp e1,它具有类型Error Val(参见 的类型签名epp)。

Val并且Error Val不是同一类型。那是你的问题。

如何解决?您需要某种方法将错误情况与其余计算分开处理。如果您已经为您的类型实现了Applicativeor类,那么几乎可以肯定这就是他们所做的。MonadError

编辑:你不包括你的定义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 回答