Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you curry any javascript function of arbitrary arity?

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?

like image 858
xiaolingxiao Avatar asked Sep 27 '13 03:09

xiaolingxiao


People also ask

What is the currying function in JavaScript?

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, …..)

What is a currying function explain with an example?

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.

Can you give an example of a curry function and why this syntax offers an advantage?

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.

What is currying function in JavaScript w3schools?

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.


1 Answers

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;
like image 143
plalx Avatar answered Sep 19 '22 11:09

plalx