Q28: Implement a curry() utility in JavaScript.
Answer
Currying transforms a function that accepts multiple arguments into a sequence of functions, each accepting one or more arguments until enough arguments have been collected.
For a function with three parameters, the curried form may support sum(1)(2)(3).
function curry(fn) {
function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function (...nextArgs) {
return curried.apply(this, [...args, ...nextArgs]);
};
}
return curried;
}
function sum(a, b, c) {
return a + b + c;
}
const curriedSum = curry(sum);
console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6
console.log(curriedSum(1)(2, 3)); // 6
Explanation
The utility uses fn.length to determine how many declared parameters the original function expects. If the collected argument count is insufficient, it returns another function that gathers additional arguments.
Important limitation
fn.length does not always equal the number of arguments a function logically requires. Default parameters, rest parameters, and functions with unusual signatures can make this approach unsuitable without an explicit arity argument.
Key Takeaways
- Currying transforms multi-argument calls into chained function calls.
- Closures retain arguments collected during earlier calls.