Y组合子:修订间差异

来自吾萌百科
无编辑摘要
 
(没有差异)

2022年2月10日 (四) 11:23的最新版本

Y组合子(Y Combinator),是在无类型Lambda演算中计算其他函数的一个不动点的高阶函数。

对于Y组合子来说,我们有[math]\displaystyle{ \textsf{Y}\ f = f }[/math]。使得对于任何函数都有[math]\displaystyle{ \textsf{Y}\ f = f\ (\textsf{Y}\ f) }[/math]

定义

通常我们使用Lambda将Y组合子定义为[math]\displaystyle{ \textsf{Y} = \lambda f.(\lambda x.f\ (x\ x))\ (\lambda x.f\ (x\ x)) }[/math]

证明

[math]\displaystyle{ (\textsf{Y}\ g) }[/math]

[math]\displaystyle{ = (\lambda f.(\lambda x.(f (x\ x))\ \lambda x.(f\ (x\ x)))\ g) }[/math]

[math]\displaystyle{ = (\lambda x.(g\ (x\ x))\ \lambda x.(g\ (x\ x))) }[/math]

[math]\displaystyle{ = (\lambda y.(g\ (y\ y))\ \lambda x.(g\ (x\ x))) }[/math]

[math]\displaystyle{ = (g\ (\lambda x.(g\ (x\ x))\ \lambda x.(g\ (x\ x)))) }[/math]

[math]\displaystyle{ = (g\ (\textsf{Y}\ g)) }[/math]

实现

在实际中也可以顺利的实现它,比如编程语言Scheme

(define Y
  (lambda (f) ((lambda (x) (f (lambda (y) ((x x) y))))
    (lambda (x) (f (lambda (y) ((x x) y)))))))

用处

用来实现递归

编程

我们还是用语言Scheme为例子,实现一个阶乘

正常情况下我们可以给函数命名来实现:

(define f (lambda (n) (cond ((= n 0) 1)
                            (else (* n (f (- n 1)))))))
(print (f 10))

但是在函数不能被命名的情况下,就用到了Y组合子:

(define Y
  (lambda (f) ((lambda (x) (f (lambda (y) ((x x) y))))
    (lambda (x) (f (lambda (y) ((x x) y)))))))
(print ((Y (lambda (f) (lambda (n) (cond ((= n 0) 1)
                            (else (* n (f (- n 1)))))))) 10))

或者:

(print (((lambda (f) ((lambda (x) (f (lambda (y) ((x x) y))))
    (lambda (x) (f (lambda (y) ((x x) y)))))) (lambda (f) (lambda (n) (cond ((= n 0) 1)
                            (else (* n (f (- n 1)))))))) 10))

Lambda

Lambda是匿名函数,Y组合子是为了解决递归时不能用名称指代原始函数的问题的。