Currying là biến hàm nhiều tham số thành chuỗi hàm mỗi lần nhận một tham số: f(a, b, c) → f(a)(b)(c).
javascript
// thường
const multiply = (a, b) => a * b
// curried
const multiplyC = (a) => (b) => a * b
const double = multiplyC(2)
double(5) // 10
double(8) // 16Giá trị thật nằm ở partial application — cố định trước vài tham số để tạo hàm chuyên biệt:
javascript
const log = (level) => (module) => (msg) =>
console.log(`[${level}][${module}] ${msg}`)
const errorLog = log('ERROR')
const dbError = errorLog('database')
dbError('mất kết nối') // [ERROR][database] mất kết nốiVà làm callback gọn hơn trong pipeline:
javascript
const prop = (key) => (obj) => obj[key]
const names = users.map(prop('name')) // thay vì (u) => u.nameHàm curry tổng quát:
javascript
const curry = (fn) => function curried(...args) {
return args.length >= fn.length
? fn.apply(this, args)
: (...rest) => curried.apply(this, [...args, ...rest])
}Lưu ý: curry dựa vào fn.length — hàm có tham số mặc định hoặc rest sẽ báo length không đúng, khiến hàm curry chờ mãi không đủ tham số.
Chốt: đừng curry mọi thứ. Nó đáng dùng khi thật sự có nhiều biến thể chỉ khác một tham số; ngoài ra bind hoặc một arrow function thường rõ ràng hơn.