这篇文章里,你会学到, 什么是函数式编程,函数式编程的特点有哪些,什么是柯里化,以及柯里化的强化例子。可以根据目录查看你需要的部分
概念
什么是函数式编程?
- 函数式编程是一种编程范式,它的核心思想是将计算过程看作一系列数学函数的组合,避免使用可变状态和可变数据,通过函数的输入和输出来描述程序的行为。
函数式编程的特点有哪些?
函数是一等公民:函数可以作为变量、参数和返回值进行传递和操作。纯函数:纯函数是指输入相同,输出也相同,而且没有任何副作用(即不会修改外部状态)的函数。不可变数据:在函数式编程中,数据是不可变的,即一旦创建就不可修改。延迟执行:函数式编程中通常采用惰性求值(也称为延迟执行)的方式,即只有在需要结果时才会计算表达式的值。
函数式编程通常采用高阶函数、闭包、柯里化、函数组合等技术,它的目标是编写简洁、可复用、易于维护和并发执行的程序。
柯里化
什么是柯里化?
- 柯里化(Currying)是一种将接受多个参数的函数转换成一系列接受单一参数的函数的技术。
- 换句话说,柯里化就是
将一个函数转换成一个返回新函数的高阶函数的过程。
例如,可以用柯里化来实现一个通用的加法函数:
function add(x: number): (y: number) => number {
return function(y: number): number {
return x + y;
};
}
let add1 = add(1); // 返回一个函数,加1
let add2 = add(2); // 返回一个函数,加2
console.log(add1(10)); // 11
console.log(add2(10)); // 12
- 定义了一个
add函数,它接受一个数字类型的参数x - 返回一个函数类型的值
(y: number) => number,这个返回的函数也接受一个数字类型的参数y - 返回值为两个参数的和
- 使用
add函数来分别创建两个新函数add1和add2
这里我们分别传入参数
1和2来调用add函数,得到两个新函数add1和add2。add1表示加 1 的操作,add2表示加 2 的操作
- 分别调用
add1和add2函数,并传入参数10来执行加法运算 - 分别使用这两个新函数来执行加法运算并输出结果,使用
console.log函数来输出结果
柯里化例子
举一个通用的柯里化函数
- 可以接受任意个数的参数
type CurryFunc<T> = (arg: T) => CurryFunc<T> | T;
function curry<T>(fn: (...args: T[]) => any): CurryFunc<T> {
return function curried(...args: T[]): CurryFunc<T> | T {
if (args.length >= fn.length) {
return fn(...args);
} else {
return function(arg: T): CurryFunc<T> | T {
return curried(...args, arg);
};
}
};
}
定义了一个泛型函数
curry,它接受一个任意个数的参数,并返回一个柯里化函数
- 这个柯里化函数可以接受任意个数的参数
- 并在最后一个参数传入后执行原始函数
对curry 做解释
- 定义了一个泛型类型
CurryFunc<T>,它表示柯里化函数的类型 - 接受一个泛型类型为
T的参数arg,并返回一个联合类型(CurryFunc<T> | T)这个联合类型表示,柯里化函数可以继续返回另一个柯里化函数,也可以返回一个最终结果 T - 函数签名中的
<T>表示这个函数是一个泛型函数 - 函数的参数
fn是一个接受多个泛型类型的参数T的函数,返回值类型可以是任意类型any - 函数体内部的
return语句返回了一个新的函数curried - 接受参数
...args,也就是一个不定长的参数数组 - 在
curried函数中,首先通过args.length和fn.length的比较来判断是否已经传入了足够的参数 - 如果已经传入了足够的参数,就直接调用原函数
fn并返回它的返回值 - 如果还没有传入足够的参数,就返回一个新的函数,这个函数接受单个参数
arg,然后将arg与之前已经传入的参数合并为一个新的参数数组,并递归调用curried函数,直到所有参数都传入为止 - 最后,整个函数的返回类型是
CurryFunc<T>,这个类型是一个联合类型,可以是函数curried或者T类型的任意值
function add(x: number, y: number, z: number): number {
return x + y + z;
}
- 定义了一个简单的原始函数
add,它接受三个数字类型的参数,并返回它们的和
let curriedAdd = curry(add);
let add1 = curriedAdd(1);
let add2 = add1(2);
console.log(add2(3)); // 6
console.log(curriedAdd(1)(2)(3)); // 6
- 使用
curry函数来创建一个新的柯里化函数curriedAdd它接受任意个数的数字类型的参数,并返回一个新的柯里化函数或执行原始函数 - 分别使用
curriedAdd函数来创建两个新的函数add1和add2 - 分别接受一个和两个数字类型的参数,并执行加法运算
- 这些新函数可以链式调用,并使用不同数量的参数来执行加法运算
- 使用这些新函数来执行加法运算并输出结果