Каррирование функции с переменным числом аргументов в JavaScript

Я пытаюсь написать функцию sum, которая принимает любое количество аргументов (с переменным числом аргументов), а также каррируется. Пример использования:

sum(5)(8)(3)             // 5 + 8 + 3             = 16
sum(2)(1)(1)(5)(3)(2)    // 2 + 1 + 1 + 5 + 3 + 2 = 14

По сути, нам нужна функция, которая строит сумму (начиная с 0), и каким-то образом эта функция возвращает значение, которое действует как простое число и как функция, которая принимает следующее значение.

Я понимаю, как каррировать стандартную функцию, и я понимаю перебор аргументов функции с переменным числом аргументов, но я не понимаю, как бы я мог каррировать функцию с переменным числом аргументов и возможно ли такое вообще.

Вот код:

sum3(1, 2, 3);         // 1 + 2 + 3         = 6
sum(1, 2, 3, 4, 5);    // 1 + 2 + 3 + 4 + 5 = 15
curry(sum3)(1)(2)(3);  // 1 + 2 + 3         = 6
curry(sum)(1)(2)(3);   // IS THIS EVEN POSSIBLE?!

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

function sum() {
  var args = Array.prototype.slice.call(arguments);
  
  return args.reduce(function (x,y) { return x + y;}, 0);
}

function curry(fn) {
  return argCollecter([]);

  function argCollecter(args) {
    return function(arg) {
      args.push(arg);

      if (args.length === fn.length) {
        return fn.apply(null, args);
      } else {
        return argCollecter(args);
      }
    }
  }
}

В настоящее время curry(sum) не делает ничего полезного, так как опирается на базовый случай args.length === fn.length, а моя вариационная функция всегда будет иметь fn.length, равное 0. Мне любопытно, есть ли другие подходы к этому, но моя интуиция подсказывает, что это просто невозможно. Если кто-нибудь может дать мне некоторое представление об этом, я был бы очень признателен!


person kaizer_roll    schedule 26.04.2016    source источник
comment
Решение может состоять в том, чтобы каррировать вариационную функцию, сохраняя результат с текущими значениями, примененными sum с помощью Object.prototype.valueOf(). Внутри curry вы можете отслеживать аргументы, что-то вроде var params = [];, и возвращать функцию, которая возвращает себя с обновленным значением.   -  person jvalen    schedule 27.04.2016