How is the curry function supposed to work?

I have a function that looks like this:

function curry(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        return fn.call(this, args.concat([].slice.call(arguments)));
    };
}

      

I always thought that the function should look and should work like:

function add(a, b, c, d) {
   return a+b+c+d;
}


curry(add, 1, 2)(3, 4);

      

but the Wikipedia article says that

it can be called a chain of functions, each with one argument

so the curry should look like this:

function curry(fn) {
    var args = [];
    return function curring() {
        args = args.concat([].slice.call(arguments));
        if (args.length >= fn.length) {
            return fn.apply(this, args);
        } else {
            return curring;
        }
    };
}

      

and will be used like this:

function add(a, b, c, d) {
   return a+b+c+d;
}

curry(add)(1)(2)(3)(4);

      

I'm right?

0


source to share


1 answer


Strictly speaking, currying converts a function with many arguments into a series of functions, each with one single argument, like in your second function curry

:

  • If you call all of them (in a chain), you end up with a complete function application that gives the same result as the original function:
    curry(add)(1)(2)(3)(4)

    returns the same as add(1, 2, 3, 4)

    , i.e.10

  • If you only call a subset, you get a partially applied function:

    • addOne = curry(add)(1);

    • addOneAndTwo = addOne(2);

    • addOneAndTwo(3)(4)

      returns 10

In Javascript, currying is usually used synonymously with partial application, as in your first function curry

. To paraphrase the Prototype Documentation :

curry curries (burns in) function arguments, returning a new function that, when called with a call, passes the original pass into the arguments in curry (along with any new ones).



For a more detailed explanation, see What is the Difference Between Currying and Private Application .

Below is a working implementation of a true curry function in javascript by Evan Borden.

A few caveats:

  • Your first function fn.call

    is wrong. You should use fn.apply

    as the array that you pass as the second argument should be used as an argument list and call

    treat it as just one argument.

  • The second function generates a currency function that can only be called once, since each invoked curring

    instance modifies the captured array args

    that was initialized when called curry

    .

    For example:

    • addOne = curry(add)(1);

      defines addOne

      with its own args

      , initialized before[1]

    • addOne(2)(3)(4)

      returns 10

      and changes args

      to[1, 2, 3, 4]

    • addOne(2)(3)(4)

      (second time) fails with addOne(...) is not a function

      ,
      like addOne(2)

      trying to calladd(1, 2, 3, 4, 2)

+1


source







All Articles