Source: https://bigfrontend.dev/problem/implement-curry
1function curry(fn) {2return curried(...args) {3if (args.length >= fn.length) {4return fn(...args);5} else {6return function innerCurried(...newArgs) {7return curried(...args, ...newArgs);8}9}10}11}
Source: https://bigfrontend.dev/problem/implement-curry-with-placeholder
1function curry(fn) {2// Return the curried function to then make more calls off of3return 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 placeholders5const canApplyFully = args.length >= fn.length && !args.slice(0, fn.length).includes(curry.placeholder);6if (canApplyFully) {7return fn.apply(this, args);8}910// Assuming we have placeholders, we will return another function to fill out the placeholders/apply the rest of the args11return function placeholderCurried(...newArgs) {12// Replace the placeholders with the new args from the next call as much as possible13const replacedArgs = args.map((arg) => {14if (arg === curry.placeholder && newArgs.length > 0) {15return newArgs.shift();16} else {17return arg;18}19});2021// Recursively call the func with the replaced args and remaining new args22return curried.apply(this, replacedArgs.concat(newArgs));23}24}25}2627curry.placeholder = Symbol()2829const join = (a, b, c) => {30return `${a}_${b}_${c}`31}3233const curriedJoin = curry(join)34const _ = curry.placeholder3536console.log(curriedJoin(1, 2, 3)); // '1_2_3'3738console.log(curriedJoin(_, 2)(1, 3)); // '1_2_3'3940console.log(curriedJoin(_, _, _)(1)(_, 3)(2)); // '1_2_3'