我不确定我做错了什么。我被卡住了,我无法再取得进展。
我将我在代码中收到的错误消息放在注释中。如果时间允许,有人可以检查我的评估功能吗?我想我在做一些非常错误的事情。
谢谢你。
我不确定我做错了什么。我被卡住了,我无法再取得进展。
我将我在代码中收到的错误消息放在注释中。如果时间允许,有人可以检查我的评估功能吗?我想我在做一些非常错误的事情。
谢谢你。
您的Let
处理程序将需要使用新绑定扩展环境,然后使用该新环境评估表达式。
您的环境是名称、Value
对的列表,但Let
包含名称、Exp
对的列表,因此您需要将Exp
s转换为Value
s 以扩展环境。请注意,eval
将a 转换Exp
为Value
.
但是,由于sLet
可以容纳多个绑定,因此您需要决定s 是并行计算还是顺序计算(lisp和lispExp
之间的区别)。绑定会影响后续绑定的值吗?根据该问题的答案,您会发现自己使用或来转换列表。let
let*
map
foldl
您对 s 的评估存在Primitive
双重问题。首先,您使用的模式只匹配一个元素的列表,但您的原语显然采用不同数量的参数。该模式不应使用列表语法,因为Primitive
构造函数保证在该位置会有一个列表。相反,您应该使用匹配任何内容的模式(例如 plain y
)。其次,该prim
函数需要一个Value
s 列表,但Primitive
构造函数包含一个 s 列表Exp
,因此您需要转换它们(但是,由于参数的评估不会影响环境,您将使用map
)。
为了让你朝着正确的方向前进,在:
eval e (Primitive x [y]) = prim x [eval e y]
该[y]
模式将仅匹配单个元素列表,该元素绑定到y
,并将[eval e y]
生成单个元素列表。您想要的是与整个列表匹配的模式,然后您希望通过应用于该列表的eval e
每个元素来转换该列表。
的也eval
有If
问题。条件、then 和 else 都是 type Exp
,但是 eval 应该返回 a Value
,所以你必须转换一些东西。最后,haskellif
希望条件是一个 haskell Bool
,但你的条件是一个Exp
。您将需要将 评估Exp
为Value
,然后以某种方式Bool
从Value
. 您希望Number
和String
Value
s 在您的语言中表现得像Bool
s(如 python),还是应该只让Bool
Value
s 表现得像Bool
s?
最后,最后,如果您有任何类型错误(例如尝试Add
aString
到 a 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 期望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