How to write an add
function so that we can call it as
add(3,5);
// and
add(3)(5);
in JavaScript?
How to write an add
function so that we can call it as
add(3,5);
// and
add(3)(5);
in JavaScript?
Here is a generic way to curry any function as long as it has all its formal parameters defined (i.e. it doesn't work with variadic functions).
function curry(f) {
return function() {
if (arguments.length >= f.length) {
return f.apply(null, arguments);
}
var args = Array.prototype.slice.call(arguments, 0);
return curry(f.bind.apply(f,[null].concat(args)));
}
}
It works by comparing the number of parameters the function accepts (exposed via the .length
property) to the number of arguments passed to the function. If less arguments are passed to the function than it accepts, it returns a new function with bound parameters.
Usage:
function add(a, b, c) {
return a + b + c;
}
add = curry(add);
console.log(add(1,1,1)); // 3
console.log(add(1,1)); // function
console.log(add(1,1)(2)); // 4
console.log(add(1)(2,2)); // 5
console.log(add(1)(2)(3)); // 6
Demo: http://jsfiddle.net/90zs4n92/
An alternative implementation which avoids binding arguments can be found here.
Perhaps this is what you want?
function addFactory(a) {
return function(b) {
return a + b;
};
}
//Make an addingFunction
var addThree = addFactory(3);
addThree(5); // returns 8
//Or, in short
addFactory(3)(5); // returns 8
You could probably make the function handle both the add(3,5)
case and the add(3)(5)
case by checking arguments.length
and the type of the arguments. However, I would imagine it would be easier and more readable just to have 2 functions with an if statement. Not sure what you're using it for.
This will work with either way:
add = function(a, b) {
if(b === undefined) {
return function(b) {
return add(a, b);
}
}
return a + b;
}
alert(add(3)(5));
alert(add(3, 5));
You want to write a curryable function - a function that takes n amount of arguments, but if you call it without all the arguments, it returns a partially applied function.
var add = function(a, b) {
if(arguments.length === 2) {
return a + b;
}
else {
return function(x) { return x + a }
}
}
var addFour = add(4);
add(4, 3); // => 7
add(4)(3); // => 7
addFour(3); // => 7
Try this
function add() {
//Check the number of arguments
var argLength = arguments.length;
//No arguments
if(argLength == 0) {
return null;
}
//Only one argument, then return another function.
if(argLength == 1) {
var first = arguments[0];
return function(second) {
return first + second;
}
}
//More than one argument, then add them all.
var output = 0;
for(var i = 0; i < argLength; i++) {
output += arguments[i];
}
return output;
}
This is the solution based on my original comment. By the way I see that everyone there had the same idea (returning a function
object.).
var add = (function(x, z) {
return (typeof(z) !== "undefined") ? x + z : function(y) { return x + y; }
});
var value = add(3)(5);
alert(value); // 8
value = add(3, 5);
alert(value); // 8
If the original goal of your question was about currying, I found a document interesting about that, using JavaScript : https://medium.com/@kbrainwave/currying-in-javascript-ce6da2d324fe
you can do this:
function add(a, b) {
if(b === undefined || arguments.length !== 2) {
return function(b) {
return add(a, b);
}
}
return a + b;
}
alert(add(3)(5));
alert(add(3, 5));
Currying is when you break down a function that takes multiple arguments into a series of functions that take part of the arguments. Here's an example in Scheme
(define (add a b)
(+ a b))
(add 3 4) returns 7
This is a function that takes two arguments, a and b, and returns their sum. We will now curry this function:
(define (add a)
(lambda (b)
(+ a b)))`
This is a function that takes one argument, a, and returns a function that takes another argument, b, and that function returns their sum.
((add 3) 4)
(define add3 (add 3))
(add3 4)
The first statement returns 7, like the (add 3 4) statement. The second statement defines a new function called add3 that will add 3 to its argument. This is what some people may call a closure. The third statement uses the add3 operation to add 3 to 4, again producing 7 as a result.