函数柯里化

柯里化(Currying)详解及JavaScript演示

柯里化是一种将多参数函数转换为一系列单参数函数的技术,是函数式编程中的重要概念。

基本概念

柯里化的核心思想是:把一个接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下参数的新函数

JavaScript实现示例

1. 简单加法函数的柯里化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 普通加法函数
function add(a, b) {
return a + b;
}

// 柯里化后的加法函数
function curriedAdd(a) {
return function(b) {
return a + b;
};
}

// 使用方式
const add5 = curriedAdd(5); // 固定第一个参数为5
console.log(add5(3)); // 输出8 (5+3)
console.log(add5(10)); // 输出15 (5+10)

2. 通用柯里化函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function curry(fn) {
return function curried(...args) {
if (args.length >= fn.length) {
return fn.apply(this, args);
} else {
return function(...args2) {
return curried.apply(this, args.concat(args2));
};
}
};
}

// 使用示例
function sum(a, b, c) {
return a + b + c;
}

const curriedSum = curry(sum);

console.log(curriedSum(1)(2)(3)); // 6
console.log(curriedSum(1, 2)(3)); // 6
console.log(curriedSum(1)(2, 3)); // 6

3. 实际应用示例:日志函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 普通日志函数
function log(date, importance, message) {
console.log(`[${date.getHours()}:${date.getMinutes()}] [${importance}] ${message}`);
}

// 柯里化后的日志函数
const curriedLog = curry(log);

// 创建特定时间的日志函数
const logNow = curriedLog(new Date());

// 创建重要级别的日志函数
const debugNow = logNow("DEBUG");

// 使用
debugNow("系统启动"); // [HH:MM] [DEBUG] 系统启动
debugNow("数据库连接成功"); // [HH:MM] [DEBUG] 数据库连接成功

柯里化的特点

  1. 参数复用:固定某些参数,生成更具体的函数
  2. 延迟执行:分步传入参数,最后一步才真正执行
  3. 函数组合:便于创建管道式的函数组合

柯里化的优点

  1. 提高代码复用性:可以基于现有函数创建更具体的函数
  2. 增强函数灵活性:支持部分参数应用
  3. 便于函数组合:使函数更容易组合和重用

柯里化 vs 部分应用

柯里化强调每次只接受一个参数,而部分应用(Partial Application)是一次可以接受多个参数

1
2
3
4
5
6
7
8
9
// 部分应用示例
function partial(fn, ...fixedArgs) {
return function(...remainingArgs) {
return fn.apply(this, fixedArgs.concat(remainingArgs));
};
}

const add5 = partial(add, 5); // 固定第一个参数为5
console.log(add5(10)); // 15

柯里化是部分应用的一种特殊形式,所有柯里化函数都可以实现部分应用,但并非所有部分应用都是柯里化。