0

Is there a way to chain a curried function such that you can have an arbitrary number of invocations? The following example only allows you to apply the function twice, the first time calling the curry function, and the second calling the add function which returns a numerical value.

var slice = Array.prototype.slice;

function curry(fn) {

    var storedArgs = slice.call(arguments, 1);

    return function () {

        var newArgs = slice.call(arguments),
            args = storedArgs.concat(newArgs);

        return fn.apply(null, args);
    }
}

function add () {
    var numbersToAdd = slice.call(arguments);
    var total = 0;
    for (var i = 0, numberCount = numbersToAdd.length; i < numberCount; i++) {
        total += numbersToAdd[i];
    }
    return total;
}

console.log(curry(add, 1000)(1, 1, 1, 1, 1, 1, 1, 1));

//does not work because number is returned rather than a function after second invocation
//console.log(curry(add, 1000)(1, 1, 1, 1, 1, 1, 1, 1)(1));
nbrooks
  • 18,126
  • 5
  • 54
  • 66
ThinkingInBits
  • 10,792
  • 8
  • 57
  • 82

2 Answers2

1

This is not possible in general, not just in JavaScript.

The result of curry(add, 1000) is a function.

Calling it with: curry(add, 1000)(1, 1, 1, 1, 1, 1, 1, 1) returns a number.

It can't return both a number and a function, it must be either.


One possibility is to make a weak curry. Something like:

create_aggregator(add, 1000).aggregate(1, 1, 1, 1, 1).aggregate(1).finalize();

Where .finalize() will give you the result number.


You could try to dabble in some black magic and make a number type that extends from Function. This is possible in JavaScript since functions are objects.

Halcyon
  • 57,230
  • 10
  • 89
  • 128
0

This is the best solution I could come up with:

function sum() {
    var total = 0;
        fn = function() {
            for(var i = 0; i < arguments.length; i++) {
                total += arguments[i];
            }
            fn.total = total;
            return fn;
        };

    return fn.apply(null, arguments);
}

The total is stored on the function as a key: total

Here's a fiddle: http://jsfiddle.net/jmeyers91/hsuf9v04/

Edit: I'm not sure how one would write a higher order function that generated this from a regular function.

SimpleJ
  • 13,812
  • 13
  • 53
  • 93