Curry
Problem
Given a function fn, return a curried version of that function.
A curried function is a function that accepts fewer or an equal number of parameters as the original function and returns either another curried function or the same value the original function would have returned.
In practical terms, if you called the original function like sum(1,2,3), you would call the curried version like csum(1)(2)(3), ``csum(1)(2,3),
csum(1,2)(3), or csum(1,2,3). All these methods of calling the curried function should return the same value as the original.
Examples
Example 1:
Input:
fn = function sum(a, b, c) { return a + b + c; }
inputs = [[1],[2],[3]]
Output: 6
Explanation:
The code being executed is:
const curriedSum = curry(fn);
curriedSum(1)(2)(3) === 6;
curriedSum(1)(2)(3) should return the same value as sum(1, 2, 3).
Example 2:
Input:
fn = function sum(a, b, c) { return a + b + c; }
inputs = [[1,2],[3]]
Output: 6
Explanation:
curriedSum(1, 2)(3) should return the same value as sum(1, 2, 3).
Example 3:
Input:
fn = function sum(a, b, c) { return a + b + c; }
inputs = [[],[],[1,2,3]]
Output: 6
Explanation:
You should be able to pass the parameters in any way, including all at once or none at all.
curriedSum()()(1, 2, 3) should return the same value as sum(1, 2, 3).
Example 4:
Input:
fn = function life() { return 42; }
inputs = [[]]
Output: 42
Explanation:
currying a function that accepts zero parameters should effectively do nothing.
curriedLife() === 42
Constraints:
1 <= inputs.length <= 10000 <= inputs[i][j] <= 10^50 <= fn.length <= 1000inputs.flat().length == fn.length- function parameters explicitly defined
- If
fn.length > 0then the last array ininputsis not empty - If
fn.length === 0theninputs.length === 1
Solution
Method 1 – Closure with Argument Accumulation
Intuition
The key idea is to use a closure to accumulate arguments until the original function's arity is satisfied, then call the original function. Each call to the curried function collects more arguments, and when enough arguments are collected, the original function is invoked.
Approach
- Define a function
currythat takes a functionfn. - Inside, define a helper function that accumulates arguments.
- If the number of accumulated arguments is at least
fn.length, callfnwith those arguments. - Otherwise, return a new function that collects more arguments.
- The closure ensures arguments are preserved across calls.
Code
JavaScript
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn(...args);
} else {
return (...next) => curried(...args, ...next);
}
};
}
TypeScript
function curry(fn: Function): Function {
return function curried(...args: any[]): any {
if (args.length >= fn.length) {
return fn(...args);
} else {
return (...next: any[]) => curried(...args, ...next);
}
};
}
Complexity
- ⏰ Time complexity:
O(1)per call, as each call just accumulates arguments or calls the original function. - 🧺 Space complexity:
O(n), where n is the number of arguments accumulated (at most fn.length).