简体   繁体   English

javascript中的Y-Combinator factorial适用于不属于教会数字的数字。

[英]Y-Combinator factorial in javascript works for numbers not for the Church numerals.

I managed to implement Church encoding and Y-Combinator using ES6 arrow function in javascript. 我设法在javascript中使用ES6箭头功能实现Church编码和Y-Combinator。 But when I tried to evaluate the factorial function, 但是当我试图评估阶乘函数时,

FALSE = a => b => b 
TRUE = a => b => a 

ZERO = f => z => z
ONE = f => z => f(z)
SIX = f => z => f(f(f(f(f(f(z))))))
isZERO = n => n(x => FALSE)(TRUE)
SUCC = n => f => z => f(n(f)(z))
MULT = n => m => f => z => n(m(f))(z)

PAIR = a => b => z => z(a)(b)
FIRST = p => p(a => b => a)
SECOND = p => p(a => b => b)
ZZ = PAIR(ZERO)(ZERO)
SS = p => PAIR(SECOND(p))(SUCC(SECOND(p)))
PRED = n => FIRST(n(SS)(ZZ))

FactGen = fact => n =>
  isZERO(n)
    (ONE)
    (MULT(n)(fact(PRED(n))))

Y = g => (x => g(y => x(x)(y))) (x => g(y => x(x)(y)))

Y(FactGen)(SIX) (x=>x+1)(0)

I got 'Uncaught RangeError: Maximum call stack size exceeded(…)' error. 我得到'Uncaught RangeError:超出最大调用堆栈大小(...)'错误。

If I change FactGen, 如果我改变FactGen,

FactGen = fact => n => n == 0 ? 1 : n * fact(n - 1)
Y(FactGen)(6)
720

It just works. 它只是有效。

What I want to know is Church numeral version of it. 我想知道的是它的教堂数字版本。 How can I achieve this? 我怎样才能做到这一点?

Your problem is that JavaScript is not lazy evaluated. 您的问题是JavaScript不是懒惰的评估。 Specifically, the isZero "if" does evaluate all of its arguments before it can check whether the first is zero. 具体来说, isZero “if”在检查第一个是否为零之前会对其所有参数进行求值。

We can fix that using an if with unit functions: 我们可以使用if with unit函数来解决这个问题:

// type Bool = a -> a -> a
// type Lazy a = () -> a
// IF :: Bool -> Lazy a -> Lazy a -> a
IF = c => a => b => c(a)(b)()

FactGen = fact => n =>
  IF(isZERO(n))
    (()=>ONE)
    (()=>MULT(n)(fact(PRED(n))))
//   ^^^^

or omit the IF wrapper and change your boolean encodings directly to 或省略IF包装器并直接将布尔编码更改为

// type Bool = Lazy a -> Lazy a -> a
FALSE = a => b => b()
TRUE = a => b => a()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM