【发布时间】:2018-08-03 07:42:50
【问题描述】:
我正在尝试在 Javascript 中“实现”Church's encoding of lambda calculus,但在编写阶乘函数时开始遇到问题:
const factorial = n => (iszero(n))(ONE)(multiply(n)(factorial(predecessor(n))));
iszero(n) 充当条件,并返回一个函数,如果n 为零,则执行它的第一个参数,否则返回第二个参数。
对任何值调用此函数都会导致堆栈溢出。
我试图简化它以找出原因:
//const ifelse = condition => a => b => condition ? a : b;
//const factorial = n => ifelse(n == 0)(1)(n * factorial(n - 1));
const ifelse = function(condition, a, b) {
if (condition) {
return a;
} else {
return b;
}
}
const factorial = function(number) {
return ifelse(number == 0, 1, number * factorial(number - 1));
}
这里调用阶乘也会导致溢出,尽管如果我们在factorial 中减少ifelse 函数,它会生成一个完美的函数阶乘函数,不会抛出:
//const factorial = n => (n == 0) ? (1) : (n * factorial(n - 1));
const factorial = function(number) {
if (number == 0) {
return 1;
} else {
return number * factorial(number - 1);
}
}
但我试图在阶乘中只使用函数,因此三元条件运算符是不可接受的(请参阅注释箭头符号)。
为什么我的 factorial 函数在对任何值调用时都会导致堆栈溢出,在仍然只使用函数(无条件)的情况下是否可以避免这种情况?
EDIT:第一段代码的定义:
const TRUE = x => y => x;
const FALSE = x => y => y;
const ZERO = f => x => x;
const ONE = f => x => f(x);
const pair = a => b => f => f(a)(b);
const first = p => p(TRUE);
const second = p => p(FALSE);
const iszero = n => n(x => FALSE)(TRUE);
const successor = n => f => x => f(n(f)(x));
const multiply = n1 => n2 => f => x => n1(n2(f))(x);
const predecessor = n => second(n(p => pair(successor(first(p)))(first(p)))(pair(ZERO)(ZERO)));
【问题讨论】:
-
请同时添加缺少的部分。
-
哇,这读起来很糟糕。难怪你会感到困惑。为什么会这样写,有什么具体原因吗?
-
实在不知道怎么写比较好,能不能编辑一下或者指出什么不清楚的地方?英语不是我的第一语言,所以我的写作有点奇怪。我添加了第二段代码以避免包含第一段的缺失部分,因为它们太多了。
-
@Martijn 你从没见过Unlambda,我猜。 :)
-
但是数学玩具玩起来很有趣;)
标签: javascript recursion arrow-functions lambda-calculus