0

我不确定我做错了什么。我被卡住了,我无法再取得进展。

我将我在代码中收到的错误消息放在注释中。如果时间允许,有人可以检查我的评估功能吗?我想我在做一些非常错误的事情。

谢谢你。

4

3 回答 3

4

您的Let处理程序将需要使用新绑定扩展环境,然后使用该新环境评估表达式。

您的环境是名称、Value对的列表,但Let包含名称、Exp对的列表,因此您需要将Exps转换为Values 以扩展环境。请注意,eval将a 转换ExpValue.

但是,由于sLet可以容纳多个绑定,因此您需要决定s 是并行计算还是顺序计算(lisp和lispExp之间的区别)。绑定会影响后续绑定的值吗?根据该问题的答案,您会发现自己使用或来转换列表。letlet*mapfoldl

您对 s 的评估存在Primitive双重问题。首先,您使用的模式只匹配一个元素的列表,但您的原语显然采用不同数量的参数。该模式不应使用列表语法,因为Primitive构造函数保证在该位置会有一个列表。相反,您应该使用匹配任何内容的模式(例如 plain y)。其次,该prim函数需要一个Values 列表,但Primitive构造函数包含一个 s 列表Exp,因此您需要转换它们(但是,由于参数的评估不会影响环境,您将使用map)。

为了让你朝着正确的方向前进,在:

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

[y]模式将仅匹配单个元素列表,该元素绑定到y,并将[eval e y]生成单个元素列表。您想要的是与整个列表匹配的模式,然后您希望通过应用于该列表的eval e每个元素来转换该列表。

的也evalIf问题。条件、then 和 else 都是 type Exp,但是 eval 应该返回 a Value,所以你必须转换一些东西。最后,haskellif希望条件是一个 haskell Bool,但你的条件是一个Exp。您将需要将 评估ExpValue,然后以某种方式BoolValue. 您希望NumberString Values 在您的语言中表现得像Bools(如 python),还是应该只让Bool Values 表现得像Bools?

最后,最后,如果您有任何类型错误(例如尝试AddaString到 a 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 期望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 回答