lambda - 如何使用 lambda 实现 let*

标签 lambda scheme lambda-calculus let

我正在做 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/

相关文章:

haskell - Haskell 如何为 System F 添加图灵完备性?

lambda-calculus - 为什么需要在 λ 演算中引入 Ycombinator?

Java8 如何使用流和 lambda 将 3 级嵌套列表转换为嵌套的 HashMap

vb.net - 从 VB.NET 中的列表中删除特定值

scheme - Common Lisp和Scheme之间的通用词汇

haskell - 用 CPS 编写的函数如何使许多事情变得明确?

lambda-calculus - 如何在 Oz 编程语言中使用 AND

Java 8 流过滤 : IN clause

python - 使用 Lambdas 从字符串表达式构建可执行函数

scheme - 如何在方案中定义子环境?