Implement curry(fn)
Implement curry(fn) that returns a curried version of fn. It must collect arguments across successive calls until at least fn.length arguments have been supplied, then invoke fn with all of them. Given const add = (a, b, c) => a + b + c, every form curry(add)(1)(2)(3), curry(add)(1, 2)(3), and curry(add)(1, 2, 3) must return 6.
function curry(fn) {
// your code here
}
Write the implementation.
Return a recursive curried(...args): if args.length >= fn.length, call fn(...args); otherwise return a new function that takes more arguments and calls curried(...args, ...next), accumulating them in the closure. fn.length (the declared arity) is the threshold, so all the partial-application forms collect arguments until enough are gathered.
- ✗Hard-coding the arity instead of reading
fn.length - ✗Assuming exactly one argument per call, breaking the
(1, 2)(3)form - ✗Sharing one mutable args array across branches so concurrent partials interfere
- →Why is
fn.lengththe right threshold, and when does it report the wrong arity? - →How would you support placeholder arguments to skip a parameter position?
Solution
Recursively accumulate arguments until their count reaches fn's declared arity fn.length.
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return (...next) => curried.apply(this, [...args, ...next]);
};
}
How it works
fn.length is the function's declared arity (its parameter count). On each call curried compares the number of gathered arguments against this threshold. If there are enough, it invokes fn with all of them. Otherwise it returns a new function that waits for the next arguments and calls curried again, merging old and new via [...args, ...next].
Each branch works with its own copy of the argument array, closed over in that call, so the forms (1)(2)(3), (1, 2)(3), and (1, 2, 3) are independent and all return 6. </content>