Source: https://bigfrontend.dev/problem/implement-curry

1
function curry(fn) {
2
return curried(...args) {
3
if (args.length >= fn.length) {
4
return fn(...args);
5
} else {
6
return function innerCurried(...newArgs) {
7
return curried(...args, ...newArgs);
8
}
9
}
10
}
11
}

Source: https://bigfrontend.dev/problem/implement-curry-with-placeholder

1
function curry(fn) {
2
// Return the curried function to then make more calls off of
3
return function curried(...args) {
4
// Base case: apply the function fully only if the length of args match up with the original function's arg length and there are no placeholders
5
const canApplyFully = args.length >= fn.length && !args.slice(0, fn.length).includes(curry.placeholder);
6
if (canApplyFully) {
7
return fn.apply(this, args);
8
}
9
10
// Assuming we have placeholders, we will return another function to fill out the placeholders/apply the rest of the args
11
return function placeholderCurried(...newArgs) {
12
// Replace the placeholders with the new args from the next call as much as possible
13
const replacedArgs = args.map((arg) => {
14
if (arg === curry.placeholder && newArgs.length > 0) {
15
return newArgs.shift();
16
} else {
17
return arg;
18
}
19
});
20
21
// Recursively call the func with the replaced args and remaining new args
22
return curried.apply(this, replacedArgs.concat(newArgs));
23
}
24
}
25
}
26
27
curry.placeholder = Symbol()
28
29
const join = (a, b, c) => {
30
return `${a}_${b}_${c}`
31
}
32
33
const curriedJoin = curry(join)
34
const _ = curry.placeholder
35
36
console.log(curriedJoin(1, 2, 3)); // '1_2_3'
37
38
console.log(curriedJoin(_, 2)(1, 3)); // '1_2_3'
39
40
console.log(curriedJoin(_, _, _)(1)(_, 3)(2)); // '1_2_3'