Reputation: 16445
I'm currently working on a programming problem in my personal time that asks that I make a javascript function that can be called in this manner.
add(1) // 1
add(1)(2) // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10
add(1)(2)(3)(4)(5); // 15
What I'm having trouble figuring out is how to make it return a value on the very last call.
For example, in order for add(1)(2)
to work, then add(1)
has to return a function, but according to the instructions add(1)
when called by itself will return 1
.
I'm assuming one way you can overcome this is to figure out how many times in succession the add
function is being called, but I cannot think of a way to achieve that. Does anyone have any hints that can point me in the right direction?
I've read these two articles (1, 2) on function currying and I understand them, but I'm not sure how to do currying when dealing with a variable number of arguments.
Upvotes: 6
Views: 1177
Reputation: 207527
It is not impossible, use valueOf().
function add(initNum) {
var sum = initNum;
var callback = function (num) {
sum += num;
return callback;
};
callback.valueOf = function () {
return sum;
};
return callback;
};
console.log(add(1)(2)==3); //true
console.log(add(1)(1)+1); //3
console.log(add(1)(2)(3).valueOf()); //6
Upvotes: 2
Reputation: 135367
It is impossible to curry a variadic function with an unknown number of arguments.
Where add
is a variadic function, you could do something like
var add5 = curryN(add, 5);
add5(1)(2)(3)(4)(5); //=> 15
var add3 = curryN(add, 3);
add3(1)(2)(3); //=> 6
There's simply no avoiding this tho because a curried function will continue to return a function until the last argument is received, at which point the computation is run.
The only other option is to create some way to "short-circuit" the arguments and notify the function that the arguments are done being sent. That would require something like
var xadd = curryUntilUndefined(add);
xadd(1)(2)(3)(4)(5)(undefined); //=> 15
Here, the undefined
signals the end of the variadic arguments. I don't really recommend this tho because of the other problems it can create for you. Not to mention, it's not particularly nice to look at.
Upvotes: 4