Каррирование... Что здесь происходит?

Просьба модераторам - не удаляйте тему. Ответа в гугле не нашел(видимо из меня плохой "гуглер").
function curry(func) {

  return function curried(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args2) {
        return curried.apply(this, args.concat(args2));
      }
    }
  };

}


function sum(a, b, c) {
  return a + b + c;
}

let curriedSum = curry(sum);

alert( curriedSum(1, 2, 3) ); // 6, всё ещё можно вызывать нормально
alert( curriedSum(1)(2,3) ); // 6, каррирование первого аргумента
alert( curriedSum(1)(2)(3) ); // 6, каррирование всех аргументов


Мне непонятно, когда, где и как здесь происходит каррирование?
Можете подсказать? На каком этапе?

1) Правильно ли я понимаю, что curriedSum(1)(2,3) - здесь в качества a - цифра 1, а в качестве b - (2,3) ? А как же c?
2) А здесь тогда как? curriedSum(1)(2)(3) - где здесь каррирование?
  • Вопрос задан
  • 326 просмотров
Решения вопроса 1
MrDecoy
@MrDecoy Куратор тега JavaScript
Верставший фронтендер
Константин, карирование оно не в вызове функции. А в том, что после вызова функции возвращается другая функция, внутри которой есть замыкание на аргумент, переданный в предыдущий вызов.

Правильно ли я понимаю, что curriedSum(1)(2,3) - здесь в качества a - цифра 1, а в качестве b - (2,3) ? А как же c?

Eсли смотреть относительно функции sum, то:
В первых круглых скобка только a = 1.
Во вторых круглых скобках b = 2 и c = 3.

А здесь тогда как? curriedSum(1)(2)(3) - где здесь каррирование?

Первый вызов вернёт функцию, которая "помнит" 1, второй вызов вернёт функцию, которая "помнит" 1+2, ну и третий вызов вернёт сумму 1+2+3.

То есть эта запись: curriedSum(1)(2)(3)
Эквивалентна этой:
let curriedSum = curry(sum); // сделали функцию sum карируемой.

var one = curriedSum(1) // так как sum ожидает 3 аргумента, то этот вызов вернёт функццию, которая помнит 1 и ожидает ещё 2 аргумента.
var onePlusTwo = one(2) // так как sum ожидает 3 аргумента, то этот вызов вернёт функццию, которая помнит 1 и 2 и ожидает ещё 1 аргумент.
var result = onePlusTwo(3) // так как sum ожидает 3 аргумента, два аргумента уже помнит функция onePlusTwo и мы передаём третий аргумент, то вернёт результат sum(1,2,3)
result == 6 // true

// При этом, мы можем в данном случае снова вызвать onePlusTwo, но уже с другим аргументом,
// и получим соответствующий результат:
onePlusTwo(7) // вернёт 10, так как onePlusTwo помнит 1+2, то есть получим sum(1,2,7) // 10.

Вот в чём и состоит смысл карирования. Иметь функцию, которая помнит какое-то значение и не требует каждый раз это значение в аргументах.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы