我试图在Java中实现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
. 将 any 应用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)
以便一个工作而另一个崩溃。
我认为正在发生的是这两个表达式并不完全相同。
一方面x => f(f)(x)
- 这会创建一个新的函数文字(因此不会立即调用它 - 只有在调用此函数时才会调用它)
另一方面f(f)
- 这在 Javascript 中是一个调用f
函数的表达式。因此,在您的情况下会导致堆栈溢出。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句