2

I'm trying to write a function sum that accepts any number of arguments (variadic) and is also curried. Example use:

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

Essentially, we want a function that builds a sum (starting at 0), and somehow that function returns a value that acts as both a plain number and as a function that accepts the next value.

I understand how to curry a standard function, and I understand looping through the arguments of a variadic function, but I don't see how I would curry a variadic function, or if such a thing is even possible.

Here's the code:

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

Currently, the curry(sum) doesn't do anything useful as it relies on the base case of args.length === fn.length, and my variadic function will always have a fn.length equal to 0. I'm curious if there are any other approaches to this, but my intuition is this simply isn't possible. If anyone can provide me some insight into this it would be greatly appreciated!

  • A solution could be to curry the variadic function, saving the result with the current values applied by `sum` using `Object.prototype.valueOf()`. Inside `curry` you could keep track of the arguments, something like `var params = [];` and return a function which returns itself with the value updated. – jvalen Apr 27 '16 at 02:01

0 Answers0