我正在使用Javascript处理Lambda表达式,并编写了以下代码:
var succRender = (x) => 'succ('+ x + ')';
var numerify = expr => ((expr)(succRender) (0));
var ZERO = f => x => (x) ;
var ONE = f => x => (f(x));
var TWO = f => x => (f(f(x)));
var THREE = f => x => (f(f(f(x))));
var PLUS = n => m => f => z => (n(f) (m(f)(z))) ;
当我打电话时:
console.log(numerify((PLUS) (TWO) (THREE)));
控制台正确答复
succ(succ(succ(succ(succ(0)))))
但是我打电话给了
console.log(numerify((PLUS) (TWO) (THREE)));
和
var PLUS = n => m => f => z => (n(f) (m(f)(z))) ;
具有四个参数... Javascript如何真正发挥这种作用?通话中f和z的“值”是什么?而Javascript如何检索那些值二来完成任务呢?
预先感谢
Ed
答案 0 :(得分:0)
让我们逐步评估它:
PLUS(TWO)
调用第一个函数并以TWO
的形式传递n
,其结果为:
m => f => z => (n(f) (m(f)(z)))
然后用(THREE)
进行调用,因此m
是THREE
,其计算结果为:
f => z => (n(f) (m(f)(z)))
现在numerify(...)
被调用,其中expr
在上一行,并且在函数内部是:
expr(succRender)(0)
因此它以f
为succRender
和z
为0
的方式调用函数。现在我们可以评估PLUS主体,因此:
n(f) (m(f)(z))
成为:
TWO(succRender) (THREE(succRender)(0))
现在对TWO
调用进行评估,其中succRender
为f
,上面的行结果为
(x => (f(f(x)))) (THREE(succRender)(0))
THREE
也是如此:
(x => f(f(x)))) ((x => (f(f(f(x)))))(0))
现在,当使用(0)
调用ut时,将评估右箭头函数,因此x
是0
(x => f(f(x))) (f(f(f(0))))
因此,现在succRender
(f
)被调用了三次,而前一次调用是重复的:
(x => f(f(x))) ("succ(succ(succ(0)))")
现在,最后一个箭头函数得到求值,succRender
又被调用两次:
"succ(succ(succ(succ(succ(0)))))"
答案 1 :(得分:0)
让我们稍微整理一下包装,以更清楚地了解正在发生的事情。我已经将PLUS
重新编写为一个更简单的函数,该函数仍然需要四个参数,只是将它们加在一起。
var PLUS = a => b => c => d => a + b + c + d;
var intermediateResult = (PLUS)(1)(2); //the parenthesis around PLUS are actually not needed
console.log("intermediateResult", intermediateResult);
var secondIntermediateResult = intermediateResult(3);
console.log("secondIntermediateResult", secondIntermediateResult);
var finalResult = intermediateResult(3)(4);
console.log("finalResult", finalResult);
如您所见,如果仅传递前两个参数,则会返回一个函数。您需要“填写”所有值才能获得结果。
现在,让我们来分解一下代码中发生的事情:
(PLUS) (TWO) (THREE)
正如我所提到的,PLUS
周围不需要括号。他们什么也没做。所以我将重写这里发生的事情:
var firstIntermediateResult = PLUS(TWO);
var secondIntermediateResult = firstIntermediateResult(THREE);
因此,您要传递前两个参数。
numerify((PLUS) (TWO) (THREE))
如果我们用之前的细分代替,则等同于
numerify(secondIntermediateResult)
因此,让我们看一下numerify
函数:
var numerify = expr => ((expr)(succRender) (0));
它接受一个名为expr
的参数,然后将succRender
传递给它。这是另一个功能,但是在理解调用顺序方面并不重要。从上面我们可以看到,它将返回另一个函数,该函数在返回结果之前需要有一个最终参数,并且该参数为0
,因此,将程序的结果重写为:
var thirdIntermediateResult = secondIntermediateResult(succRender);
var finalResult = thirdIntermediateResult(0);
因此,提供所有参数后的PLUS
的最终形式如下
n(f) (m(f)(z)) --> TWO(succRender)(THREE(succRender)(0))