何が間違っているのか正確にはわかりません。私は立ち往生していて、もう進歩することができません。
コードに表示されるエラーメッセージをコメントに入れます。時間が許せば、誰かが私の評価機能をチェックしてくれませんか?私はひどく間違ったことをしていると思います。
ありがとうございました。
何が間違っているのか正確にはわかりません。私は立ち往生していて、もう進歩することができません。
コードに表示されるエラーメッセージをコメントに入れます。時間が許せば、誰かが私の評価機能をチェックしてくれませんか?私はひどく間違ったことをしていると思います。
ありがとうございました。
ハンドラーLet
は、新しいバインディングを使用して環境を拡張してから、その新しい環境を使用して式を評価する必要があります。
ご使用の環境は名前とペアのリストですValue
が、には名前とペアLet
のリストが含まれているため、環境を拡張するにはsをsExp
に変換する必要があります。をに変換することに注意してください。Exp
Value
eval
Exp
Value
ただし、はLet
複数のバインディングを保持できるため、sを並行して評価するか、順次評価するか( lispとExp
の違い)を決定する必要があります。バインディングは、後続のバインディングの値に影響を与える可能性がありますか?その質問への回答に応じて、またはを使用してリストを変換することになります。let
let*
map
foldl
Primitive
sの評価に関するあなたの問題は2つあります。まず、1つの要素のリストとのみ一致するパターンを使用していますが、プリミティブは明らかに異なる数の引数を取ります。Primitive
コンストラクターはその位置にリストがあることを保証するため、パターンはリスト構文を使用しないでください。代わりに、(plainのように)何にでも一致するパターンを使用する必要がありますy
。次に、prim
関数はValue
sのリストを期待していますが、Primitive
コンストラクターにはのリストが含まれているExp
ため、それらを変換する必要があります(ただし、引数の評価は環境に影響を与えないため、を使用しますmap
)。
あなたを正しい方向に導くために、次のように:
eval e (Primitive x [y]) = prim x [eval e y]
[y]
パターンは単一の要素リストにのみ一致し、その要素はにバインドされy
、[eval e y]
単一の要素リストになります。必要なのは、リスト全体に一致するパターンであり、次に、そのeval e
リストの各要素に適用することによって、そのリストを変換する必要があります。
のeval
にIf
も問題があります。条件、then、elseはすべてタイプですExp
が、evalはを返すことValue
になっているため、何かを変換する必要があります。最後に、haskellif
は条件がhaskellであることを望んBool
でいますが、あなたの条件はExp
です。を評価してから、どういうわけかからhaskellを抽出する必要Exp
がありValue
ます。とsを自分の言語のsのように(pythonのように)動作させたいですか、それともsだけをsのように動作させる必要がありますか?Bool
Value
Number
String
Value
Bool
Bool
Value
Bool
最後に、最後に、タイプエラーがある場合(Add
aString
をしようとするなどNumber
)、またはプリミティブに間違った数の引数を指定すると、prim
関数から(場合によってはコードで)パターン一致の失敗が発生します。Bool
あなたの状態からを抽出するために書く必要がありますIf
)。それはあなたが望むものかもしれないし、そうでないかもしれません...
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")]))
あなたは次のようなものが欲しい
let e' = {- extend env with x -} in eval e' y