Difficulty: Intermediate
What is currying in JavaScript? How does it differ from partial application, and what is function composition?
Currying transforms a function that takes multiple arguments into a sequence of functions each taking a single argument: f(a, b, c) becomes f(a)(b)(c).
Partial application fixes some arguments of a function, returning a new function expecting the remaining ones. Unlike currying, partial application is not strictly one-argument-at-a-time.
Function composition combines functions so the output of one becomes the input of the next. compose(f, g)(x) = f(g(x)). pipe is the same but left-to-right.
const add = (a) => (b) => a + b;
const add5 = add(5);
console.log(add5(3));
console.log(add5(10));
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
}
return function(...args2) {
return curried.apply(this, args.concat(args2));
};
};
}
const multiply = curry((a, b, c) => a * b * c);
console.log(multiply(2)(3)(4));
console.log(multiply(2, 3)(4));
console.log(multiply(2, 3, 4));
A generic curry function checks if enough arguments have been supplied. If yes, calls the original; if not, returns a new function accumulating args.
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);
const compose = (...fns) => x => fns.reduceRight((v, f) => f(v), x);
const double = x => x * 2;
const addOne = x => x + 1;
const square = x => x * x;
const transform = pipe(double, addOne, square);
console.log(transform(3));
const processUsers = pipe(
users => users.filter(u => u.active),
users => users.map(u => u.name.trim()),
names => names.sort()
);
const users = [
{ name: ' Bob ', active: true },
{ name: 'Alice', active: false },
{ name: 'Charlie', active: true }
];
console.log(processUsers(users));
pipe creates readable data transformation pipelines. Each function receives the output of the previous one.
Currying, Partial Application, Function Composition, pipe, compose