JavaScript Стрелка Функция и проблема закрытия - PullRequest
0 голосов
/ 19 октября 2018

Я работаю над лямбда-выражением в Javascript и написал следующий код:

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

Ответы [ 2 ]

0 голосов
/ 19 октября 2018

Давайте немного распакуем вещи, чтобы увидеть, что происходит более четко.Я переписал 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))
0 голосов
/ 19 октября 2018

Давайте оценим это шаг за шагом:

  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))

Теперь функция стрелки вправо оценивается как вызов ut с (0), поэтому x0

 (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)))))"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...