在Scheme中理解Y组合子中的额外参数

在Scheme中理解Y组合子中的额外参数,scheme,y-combinator,Scheme,Y Combinator,根据,方案中的Y组合器实现为 (define Y (λ (h) ((λ (x) (x x)) (λ (g) (h (λ args (apply (g g) args))))))) 当然,传统的Y组合是λf.(λx.f(x x))(λx.f(x x)) 那么,我的问题是关于h和args,它们没有出现在数学定义中,而关于apply,它似乎应该在组合子的两个部分中,或者两者都不在 有人能帮我理解这里发生了什么吗?让我们从lambda演算版本开始,计划: (λ(f)

根据,方案中的Y组合器实现为

(define Y
  (λ (h)
    ((λ (x) (x x))
     (λ (g)
       (h (λ args (apply (g g) args)))))))
当然,传统的Y组合是λf.(λx.f(x x))(λx.f(x x))

那么,我的问题是关于
h
args
,它们没有出现在数学定义中,而关于
apply
,它似乎应该在组合子的两个部分中,或者两者都不在


有人能帮我理解这里发生了什么吗?

让我们从lambda演算版本开始,计划:

(λ(f)
((λ(x)(f(x)))
(λ(x)(f(x)))
我想简化一下,因为我看到
(λ(x)(fx))
重复了两次。您可以将开头替换为:

(λ(f)
((λ(b)(b))
(λ(x)(f(x)))
Scheme是一种渴望的语言,因此它将进入一个无限循环。为了避免我们做了一个代理。。假设你有两个数的
+
,你可以用
(λ(ab)(+ab))
替换它而不改变结果。让我们使用以下代码执行此操作:

(λ(f)
((λ(b)(b))
(λ(x)(f(λ)(p)((x)p))
实际上,它有自己的名字。它被称为Z组合器<仅当应用提供的代理时,才应用
f
时,不会执行code>(x)。推迟了一步。这可能看起来很奇怪,但我知道
(x x)
变成了一个函数,因此这与上面的
+
替换完全相同

在Lambda演算中,所有函数都有一个参数。如果您看到
fxy
,它实际上与Scheme中的
((fx)y)
相同。如果你想让它处理所有的算术函数,你的替换需要反映这一点。在Scheme中,我们有rest参数,并应用来实现这一点

(λ(f)
((λ(b)(b))
(λ(x)(f(λp)(应用(x)p()))
如果您只打算使用lambda演算中的一个arity函数,则不需要这样做

请注意,在代码中使用的是
h
而不是
f
。你怎么称呼变量并不重要。这是具有不同名称的相同代码。所以这是一样的:

(λ(rec-fun)
((λ(yfun)(yfun-yfun))
(λ(自)(rec fun)(λargs(apply(自)args((apply)((

不用说,
(yfun-yfun)
(self-self)
做了同样的事情。

区别在于,在纯lambda演算中,每个函数只接受一个参数,而在Scheme中,一个函数可以有零个或多个参数。您可以从使用的符号中看到这一点:
λargs
将args绑定到整个参数列表,并且需要
apply
,因为
(g)
的结果必须应用到所有参数,并且不能用直接符号在Scheme中编写。