【发布时间】:2017-02-25 15:39:28
【问题描述】:
我试图在 Javascript 中实现 Y 组合器。
我设法实现了以下内容:
const y0 = gen => (f => f(f))( f => gen( x => f(f)(x) ) );
const factorial0 = y0( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial0(5));
// 120
效果很好。
然后我在考虑表达式x => f(f)(x)。
我的理解是表达式x => g(x)等价于g。将任何y 应用于x => g(x) 计算结果为g(y),而将y 应用于g 也计算结果为g(y)。
所以我将x => f(f)(x) 替换为f(f)。
const y = gen => (f => f(f))( f => gen( f(f) ) );
const factorial = y( fact => n => n<=2 ? n : n * fact(n-1) );
console.log(factorial(5));
// RangeError: Maximum call stack size exceeded
但是这个版本会因堆栈溢出而崩溃。
那么x => f(f)(x) 和f(f) 有什么区别,一个工作,另一个崩溃。
【问题讨论】:
-
因为严格的评价。
-
@Bergi 三个字——我称之为懒惰的解释:D
标签: javascript lambda functional-programming lazy-evaluation evaluation