从“函数”的角度来看,y组合子是一个计算机科学的概念。大多数程序员根本不了解组合子,如果他们听说过的话。
什么是y组合子? 组合符是如何工作的? 它们有什么用? 它们在过程语言中有用吗?
从“函数”的角度来看,y组合子是一个计算机科学的概念。大多数程序员根本不了解组合子,如果他们听说过的话。
什么是y组合子? 组合符是如何工作的? 它们有什么用? 它们在过程语言中有用吗?
当前回答
上面的大多数答案描述了y组合子是什么,但没有描述它的用途。
用不动点组合子来证明lambda演算是图灵完备的。这是计算理论中一个非常重要的结果,为函数式编程提供了理论基础。
学习不动点组合子也帮助我真正理解了函数式编程。但我从未发现它们在实际编程中有任何用处。
其他回答
不动点组合子(或不动点运算符)是一种高阶函数,用于计算其他函数的一个不动点。此操作与编程语言理论相关,因为它允许以重写规则的形式实现递归,而不需要语言的运行时引擎的显式支持。(src维基百科)
为了帮助自己掌握Y-Combinator,我在Clojure和Scheme中都写了一份关于Y-Combinator的“傻瓜指南”。他们受到了《小阴谋家》的影响
在方案: https://gist.github.com/z5h/238891
Clojure: https://gist.github.com/z5h/5102747
这两个教程都是代码中穿插的注释,应该剪切和粘贴到您最喜欢的编辑器。
y组合子实现匿名递归。所以与其
function fib( n ){ if( n<=1 ) return n; else return fib(n-1)+fib(n-2) }
你可以这样做
function ( fib, n ){ if( n<=1 ) return n; else return fib(n-1)+fib(n-2) }
当然,y-combinator只适用于按名字命名的语言。如果你想在任何正常的值调用语言中使用它,那么你将需要相关的z-combinator (y-combinator将发散/无限循环)。
其他答案对此提供了相当简洁的答案,但没有一个重要的事实:你不需要用任何实用语言以这种令人费解的方式实现定点组合子,这样做没有任何实际目的(除了“看,我知道y组合子是什么”)。这是一个重要的理论概念,但没有什么实际价值。
下面是Y-Combinator和Factorial函数的JavaScript实现(来自Douglas Crockford的文章,可在http://javascript.crockford.com/little.html上找到)。
function Y(le) {
return (function (f) {
return f(f);
}(function (f) {
return le(function (x) {
return f(f)(x);
});
}));
}
var factorial = Y(function (fac) {
return function (n) {
return n <= 2 ? n : n * fac(n - 1);
};
});
var number120 = factorial(5);