私が書いているミニ Haskell コンパイラの一部として、 という名前の関数がありますapp。この関数に実行させたいのは、これらの引数を取り込むことですepp (App e1 e2)。最初のステップは、e1再帰的に評価し ( epp e1)、出力がエラーになるかどうかを確認することです。そうでない場合は、評価e2してから別の関数を呼び出して、それぞれ およびとして定義したおよびeppValsの呼び出しの出力を評価します。e1e2v1v2
1 に答える
1
あなたのhpasteには、上記の質問でappVals名前が変更された関数があります。eppValsこれは役に立ちません。
いくつかのタイプを見てみましょう:
epp :: Exp -> Error ValappVals :: 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同じタイプではありません。それはあなたの問題だ。
修正方法は?エラーケースを残りの計算とは別に処理する何らかの方法が必要です。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)
これで書き直せる
epp (App e1 e2) = eppVals <$> epp e1 <*> epp e2
于 2012-11-17T10:56:14.337 に答える