Learn the concept
Currying & Partial Application
Currying transforms a function that takes multiple arguments into a sequence of functions each taking one argument: f(a, b, c) becomes f(a)(b)(c). Partial application fixes some arguments of a function and returns a new function for the remaining ones.
Currying converts a multi-argument function into nested single-argument functions:
add(1, 2) → add(1)(2)Partial Application fixes one or more arguments:
multiply(2, 3) → double = multiply.bind(null, 2) → double(3)Benefits:
Currying vs Partial Application:
// Basic currying
const add = (a) => (b) => a + b;
add(1)(2); // 3
const addFive = add(5);
addFive(3); // 8
addFive(10); // 15
// Practical: logging with context
const log = (level) => (module) => (message) =>
console.log(`[${level}] ${module}: ${message}`);
const errorLog = log('ERROR');
const authError = errorLog('Auth');
authError('Invalid token'); // [ERROR] Auth: Invalid token
authError('Session expired'); // [ERROR] Auth: Session expired
// Curried API request
const request = (method) => (url) => (data) =>
fetch(url, { method, body: JSON.stringify(data) });
const post = request('POST');
const createUser = post('/api/users');
await createUser({ name: 'Alice' });Creating pre-configured event handlers like onClick(id) that returns (event) => handleClick(id, event)
Express/Koa middleware patterns where middleware(config) returns (req, res, next) => ... for configurable behavior
Creating reusable validators like minLength(5) returning (value) => value.length >= 5 for composable validation
Build composable validators using curried functions (minLength, maxLength, matches, isEmail) that chain together
Build a pipe function that composes curried transformation functions for data processing workflows