Let's say I have some function:
function g(a,b,c){ return a + b + c }
And I'd like to turn it into its "curried" form (in quotations since it's not exactly curried per se):
function h(a,b,c){
switch(true){
case (a !== undefined && b !== undefined && c !== undefined):
return a + b + c
case (a !== undefined && b !== undefined && c === undefined):
return function(c){ return a + b + c }
case (a !== undefined && b == undefined && c === undefined ):
return function(b,c){
return (c === undefined) ? function(c){ return a + b + c } : a + b + c
}
default:
return h
}
}
The above form has the partial binding behavior I want:
h(1) -> h(b,c)
h(1,2) -> h(c)
h(1,2,3) -> 6
h() -> h(a,b,c)
Now I'd like to automate this process into some generic function curry
such that given any un-curried function (and maybe its number of parameters), the above function is generated. But I'm not quite sure how to implement it.
Alternatively, if the following form could be automatically created, it'd be also interesting:
function f(a,b,c){
return function(a){ return function(b){ return function(c){ return a + b + c }}}
}
Though binding f
looks like this:
f(1)(2)(3) = 6
so it is very unwieldily and non-idiomatic, but creating the above form seem more feasible to me.
Now is could any of the above form be generated by some function, if so, how?
It is a technique in functional programming, transformation of the function of multiple arguments into several functions of a single argument in sequence. The translation of function happens something like this, function simpleFunction(param1, param2, param3, …..)
Currying is when you break down a function that takes multiple arguments into a series of functions that each take only one argument. Here's an example in JavaScript: function add (a, b) { return a + b; } add(3, 4); // returns 7. This is a function that takes two arguments, a and b, and returns their sum.
Curry functions are neat when used to carry containers of reusable code. Basically you take a function with multiple arguments and you know that one of those arguments will have specific value but the other is undecided.
Currying is an advanced technique of working with functions. It's used not only in JavaScript, but in other languages as well. Currying is a transformation of functions that translates a function from callable as f(a, b, c) into callable as f(a)(b)(c) . Currying doesn't call a function. It just transforms it.
I believe that you could simply use Function.prototype.bind
. That gives you all the flexibility you need, wheter you want the result of the function right away or simply push another value into the arguments until you decide to execute.
function sum() {
return [].reduce.call(arguments, function (c, n) {
return c + n;
});
}
sum(1, 2); //3
var sum2 = sum.bind(null, 1, 2);
sum2(); //3
var sum3 = sum2.bind(null, 3);
sum3(); //6
You could also use a helper function like:
function curry(fn) {
var c = curry.bind(this, fn = fn.bind.apply(fn, [this].concat([].slice.call(arguments, 1))));
c.exec = fn;
return c;
}
curry(sum, 1, 2)(3)(4, 5)(6, 7, 8).exec(); //36
Also this is very flexible as you do not have to chain, you can re-use the same curried function.
var sumOnePlus = curry(sum, 1);
sumOnePlus.exec(2); //3;
sumOnePlus.exec(3); //4;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With