柯里化本身不直接实现函数组合或管道,而是将多参数函数转为单参数函数链,使函数能参与pipe/compose等组合操作,从而支持部分应用和顺序拼接。

JavaScript 中柯里化本身不直接实现函数组合或管道,但它为组合与管道提供了更灵活、可复用的基础——核心在于把多参数函数转为一系列单参数函数,从而支持部分应用和顺序拼接。
柯里化是组合与管道的“适配器”
原生函数(如 (a, b, c) => a + b * c)无法直接用于 compose(f, g) 或 pipe(a, b, c),因为组合/管道要求每个函数只接收一个输入、返回一个输出。柯里化把函数“拉直”,让中间结果能自然流入下一个函数:
- 柯里化后:
add = (a) => (b) => a + b,add(2)(3)返回5 - 这样
pipe(x => x * 2, add(3), Math.sqrt)才能逐层传递单一值 - 未柯里化的
Math.pow(base, exp)必须先写成(base) => (exp) => Math.pow(base, exp)或用通用柯里化工具处理
手动实现可组合的柯里化函数
不依赖库时,可手写一个支持自动柯里化且兼容组合的版本:
const curry = (fn) => {
const curried = (...args) => {
if (args.length >= fn.length) return fn(...args);
return (...more) => curried(...args, ...more);
};
return curried;
};
<p>// 示例:可直接用于 pipe/compose
const multiply = curry((a, b) => a <em> b);
const add = curry((a, b) => a + b);
const square = (x) => x </em> x;</p><p>// 管道:输入 → ×3 → +5 → 平方
const pipeline = pipe(multiply(3), add(5), square);
console.log(pipeline(2)); // ((2*3)+5)^2 = 121
</p>
用 pipe/compose 封装柯里化链式调用
管道(pipe)从左到右执行,组合(compose)从右到左,两者都依赖单参函数。柯里化让任意函数“达标”:
const pipe = (...fns) => (x) => fns.reduce((acc, f) => f(acc), x);
const compose = (...fns) => (x) => fns.reduceRight((acc, f) => f(acc), x);
<p>// 柯里化后,即使是带默认行为的函数也能参与
const formatPrice = curry((currency, decimals, value) =>
<code>${currency}${value.toFixed(decimals)}</code>
);
const usd = formatPrice('$')(2); // 预设货币和精度</p><p>// 现在可以管道化处理数值流
const toUSD = pipe(Math.round, x => x / 100, usd);
console.log(toUSD(12345)); // "$123.45"
</p>
注意边界:柯里化 ≠ 自动管道,需显式连接
柯里化只是让函数“准备好被管道调用”,它本身不执行组合逻辑。常见误区:
- ❌
curry(fn)(a)(b)是调用,不是组合;要组合得用pipe(curry(fn)(a), g)或compose(g, curry(fn)(a)) - ✅ 若函数本就单参(如
x => x + 1),无需柯里化,可直接进pipe - ⚠️ 柯里化函数若提前收齐参数(如
add(1)(2)),会立即求值,失去延迟组合能力;应保持“等待首个输入”的形态(如add(1))才适合管道
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











