私が書いているミニ 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
型にまたは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 に答える