我正在做 lambda 演算,在我的教科书中,它说明了如何使用 lambda 演算编写 let*
。
我的答案:x、y、z是参数; v1、v2 和 v3 参数; e 是主体:
((lambda (x y z) (e)) v1 v2 v3)
书上的答案:
((lambda(x)
((lambda(y)
((lambda(z) e) v3))
v2))
v1)
我不确定我的答案是否等效。如果不是,为什么我的答案是错误的?原始答案如何得出?
最佳答案
更新 2:我意识到我原来的答案是正确的,并回滚到原来的答案,但会添加一些澄清说明。
在方案中,let*
允许后面的值依赖于前面的值。例如,您可以编写(使用通常的语法):
(let* ((foo 3)
(bar (+ foo 1))
(baz (* bar 2)))
(* foo bar baz))
绑定(bind) foo
至 3、bar
至 4、baz
到 8,并返回 72。您的教科书的实现允许这样做。
但是,您的实现不允许这样做 - 它需要独立评估所有值。然而,它是 let
的正确实现。 ,只是不是let*
.
教科书的答案的工作方式是,较早的值先于较晚的值绑定(bind)。 例如,上面课本上的代码的实现如下:
((lambda (foo)
((lambda (bar)
((lambda (baz) (* foo bar baz)) (* bar 2)))
(+ foo 1)))
3)
但是,如果您尝试以相同的方式使用您的实现:
((lambda (foo bar baz) (* foo bar baz)) 8 (+ foo 1) (* bar 2))
; Error - foo and bar aren't bound
然后是foo
在(+ foo 1)
将不受约束,如 foo
不在范围内(与 bar
中的 (* bar 2)
相同。
作为旁注,(e)
在你的实现中实际上应该是 e
,如教科书的实现;前者是一个 thunk 调用,而后者只是一个表达式。
关于lambda - 如何使用 lambda 实现 let*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23464326/