0

何が間違っているのか正確にはわかりません。私は立ち往生していて、もう進歩することができません。

コードに表示されるエラーメッセージをコメントに入れます。時間が許せば、誰かが私の評価機能をチェックしてくれませんか?私はひどく間違ったことをしていると思います。

ありがとうございました。

4

3 に答える 3

4

ハンドラーLetは、新しいバインディングを使用して環境を拡張してから、その新しい環境を使用して式を評価する必要があります。

ご使用の環境は名前とペアのリストですValueが、には名前とペアLetのリストが含まれているため、環境を拡張するにはsをsExpに変換する必要があります。をに変換することに注意してください。ExpValueevalExpValue

ただし、はLet複数のバインディングを保持できるため、sを並行して評価するか、順次評価するか( lispとExpの違い)を決定する必要があります。バインディングは、後続のバインディングの値に影響を与える可能性がありますか?その質問への回答に応じて、またはを使用してリストを変換することになります。letlet*mapfoldl

Primitivesの評価に関するあなたの問題は2つあります。まず、1つの要素のリストとのみ一致するパターンを使用していますが、プリミティブは明らかに異なる数の引数を取ります。Primitiveコンストラクターはその位置にリストがあることを保証するため、パターンはリスト構文を使用しないでください。代わりに、(plainのように)何にでも一致するパターンを使用する必要がありますy。次に、prim関数はValuesのリストを期待していますが、Primitiveコンストラクターにはのリストが含まれているExpため、それらを変換する必要があります(ただし、引数の評価は環境に影響を与えないため、を使用しますmap)。

あなたを正しい方向に導くために、次のように:

eval e (Primitive x [y]) = prim x [eval e y]

[y]パターンは単一の要素リストにのみ一致し、その要素はにバインドされy[eval e y]単一の要素リストになります。必要なのは、リスト全体に一致するパターンであり、次に、そのeval eリストの各要素に適用することによって、そのリストを変換する必要があります。

evalIfも問題があります。条件、then、elseはすべてタイプですExpが、evalはを返すことValueになっているため、何かを変換する必要があります。最後に、haskellifは条件がhaskellであることを望んBoolでいますが、あなたの条件はExpです。を評価してから、どういうわけかからhaskellを抽出する必要ExpがありValueます。とsを自分の言語のsのように(pythonのように)動作させたいですか、それともsだけをsのように動作させる必要がありますか?BoolValueNumberString ValueBoolBool ValueBool

最後に、最後に、タイプエラーがある場合(AddaStringをしようとするなどNumber)、またはプリミティブに間違った数の引数を指定すると、prim関数から(場合によってはコードで)パターン一致の失敗が発生します。Boolあなたの状態からを抽出するために書く必要がありますIf)。それはあなたが望むものかもしれないし、そうでないかもしれません...

于 2013-02-02T21:20:16.960 に答える
3

Thomas M. DuBuissonがすでに述べたように、let式の構文は無効です。次に、関数が取る引数のタイプと、関数が返すタイプを本当に知っておく必要があります。たとえば、ExpとValueを混在させることはできません。たとえば、Expタイプが予想される場合は、常にExpタイプなどの値を渡す必要があります。

eval :: Env -> Exp -> Value
-- the return type is Value
-- what are you trying to do here ? extract Value from x ...
eval e (Let [x] y) = eval e $ snd x
-- ... or from y ? Both x & y are of Exp type.
eval e (Let [x] y) = eval e y

コードにはさらに多くのタイプエラーがあります。

eval e (Primitive x [y]) = prim x [y]
-- prim expects 2nd argument of [Value] type so it can be written as
eval e (Primitive x [y]) = prim x [eval e y]
-- dtto, mixing different types is wrong
eval e (If x y z) = if x then y else z
eval e (If x y z) = let Bool x' = eval e x in
                        if x' then (eval e y) else (eval e z)

そして最後に、mainはreturnタイプとして期待IO ()しているので、eval結果を出力するように、これを何らかの形で反映する必要があります。

print $ eval [("y", (Number 40))] (Let [("x", (Literal (Number 2)))] (Primitive Add [(Variable "x"), (Variable "y")]))
于 2013-02-02T11:05:16.400 に答える
1

あなたは次のようなものが欲しい

let e' = {- extend env with x -} in eval e' y 
于 2013-02-02T08:07:00.067 に答える