0

私が書いているミニ Haskell コンパイラの一部として、 という名前の関数がありますapp。この関数に実行させたいのは、これらの引数を取り込むことですepp (App e1 e2)。最初のステップは、e1再帰的に評価し ( epp e1)、出力がエラーになるかどうかを確認することです。そうでない場合は、評価e2してから別の関数を呼び出して、それぞれ およびとして定義したおよびeppValsの呼び出しの出力を評価します。e1e2v1v2

4

1 に答える 1

1

あなたのhpasteには、上記の質問でappVals名前が変更された関数があります。eppValsこれは役に立ちません。

いくつかのタイプを見てみましょう:

  • 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)。

ValError 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 に答える