问题
I have function that look 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's how the function should look like and should work as:
function add(a, b, c, d) {
return a+b+c+d;
}
curry(add, 1, 2)(3, 4);
but Wikipedia Article says that
it can be called as a chain of functions, each with a single 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 be used as this:
function add(a, b, c, d) {
return a+b+c+d;
}
curry(add)(1)(2)(3)(4);
Am I right?
回答1:
Strictly speaking, currying converts a function with many arguments into a series of functions each with one single argument, as in your second curry
function:
If you call all of them (in chain), you get the full application of the function, which produces the same result as the original function:
curry(add)(1)(2)(3)(4)
returns the same asadd(1, 2, 3, 4)
, i.e.10
If you call only a subset, you get a partially applied function:
addOne = curry(add)(1);
addOneAndTwo = addOne(2);
addOneAndTwo(3)(4)
returns10
In Javascript, currying is usually used as a synonym for partial application, as in your first curry
function. Paraphrasing Prototype documentation:
curry curries (burns in) arguments to a function, returning a new function that when called with call the original passing in the curried arguments (along with any new ones).
For more detailed explanations, see What is the difference between currying and partial application.
Here is a working implementation of a true curry function in javascript by Evan Borden.
A few caveats:
In your first function,
fn.call
is wrong. You must usefn.apply
, as the array that you pass as the second argument must be used as a list of arguments andcall
treats it as only one argument.Your second function generates a curried function that can be called only 1 time, as each called
curring
instance modify the capturedargs
array, which was initialized whencurry
was called.For example:
addOne = curry(add)(1);
definesaddOne
with its ownargs
initialized to[1]
addOne(2)(3)(4)
returns10
and modifyargs
to[1, 2, 3, 4]
addOne(2)(3)(4)
(a second time) fails withaddOne(...) is not a function
,
asaddOne(2)
tries to calladd(1, 2, 3, 4, 2)
来源:https://stackoverflow.com/questions/18431457/how-curry-function-should-really-work