Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javascript中的Y-Combinator阶乘适用于数字,而不是教堂数字。_Javascript_Lambda Calculus_Y Combinator_Church Encoding - Fatal编程技术网

javascript中的Y-Combinator阶乘适用于数字,而不是教堂数字。

javascript中的Y-Combinator阶乘适用于数字,而不是教堂数字。,javascript,lambda-calculus,y-combinator,church-encoding,Javascript,Lambda Calculus,Y Combinator,Church Encoding,我在javascript中使用ES6 arrow函数实现了Church编码和Y-Combinator。但当我试图计算阶乘函数时 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

我在javascript中使用ES6 arrow函数实现了Church编码和Y-Combinator。但当我试图计算阶乘函数时

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)
我得到了“UncaughtRangeError:超过最大调用堆栈大小(…)”错误

如果我换了FactGen

FactGen = fact => n => n == 0 ? 1 : n * fact(n - 1)
Y(FactGen)(6)
720
它只是工作

我想知道的是它的教会数字版本。
我怎样才能做到这一点呢?

您的问题是JavaScript不是惰性的。具体地说,
isZero
“if”在检查第一个参数是否为零之前,会计算其所有参数

我们可以使用带有单位函数的
if
来解决这个问题:

// 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))))
//   ^^^^
或者省略
IF
包装器,将布尔编码直接更改为

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

谢谢。贝吉。FactGen=fact=>n=>isZERO(n)(()=>ONE)(()=>MULT(n)(fact(PRED(n)))成功了!