什么是纯函数,纯函数在函数式编程中有什么作用?

1,236 阅读4分钟

什么是纯函数?

纯函数是指在函数的执行过程中,不会对程序的状态进行任何改变,也不会对外部环境产生任何副作用,即只依赖于其输入参数,而不依赖于任何外部变量或状态的函数。

纯函数的特征

1、相同的输入总是产生相同的输出,即函数的输出只由输入决定,不受外部状态或副作用的影响。

2、函数对外部状态没有依赖,也不会改变外部状态,即不会对程序的其他部分产生任何副作用。

3、函数不会修改传入的参数,而是返回一个新的值,保持输入参数的不可变性。

4、函数的执行过程对于调用者来说是透明的,即调用者不需要了解函数的内部实现细节,只需要关注输入和输出。

 

写出高质量的纯函数,提高程序的可读性、可维护性和可扩展性,需要遵循以下原则:

  1、函数的输入和输出要明确:

纯函数的输入和输出应该是明确的,输入是指函数的参数,输出是指函数的返回值。函数的输入应该尽可能地简单和明确,而输出应该只包含必要的信息。

例如,下面是一个纯函数的例子:

function add(a, b) {
  return a + b;
}

 

2、避免修改函数的输入参数:

纯函数不会修改传入的参数,而是返回一个新的值。这样可以保持输入参数的不可变性,避免产生副作用。

例如,下面是一个不纯的函数的例子:

// 不纯函数,修改了传入的参数
function addOne(arr) {
  for (let i = 0; i < arr.length; i++) {
    arr[i] = arr[i] + 1;
  }
}

修改后的纯函数示例:

// 纯函数,不修改传入的参数
function addOne(arr) {
  return arr.map((num) => num + 1);
}

3、避免对全局变量和外部状态的依赖:

纯函数应该尽可能地避免对全局变量和外部状态的依赖,因为这样会产生副作用。

例如,下面是一个不纯的函数的例子:

// 不纯函数,依赖了全局变量
let counter = 0;

function increment() {
  counter++;
}

修改后的纯函数示例:

// 纯函数,不依赖全局变量
function increment(counter) {
  return counter + 1;
}

4、避免产生副作用:

纯函数不会对程序的其他部分产生任何副作用,包括修改全局变量、修改传入的参数等。

例如,下面是一个不纯的函数的例子:

// 不纯函数,修改了全局变量
let counter = 0;

function increment() {
  counter++;
}

修改后的纯函数示例:

// 纯函数,不修改全局变量
function increment(counter) {
  return counter + 1;
}

5、确定函数的输入和输出类型:

纯函数应该确定函数的输入和输出类型,这样可以提高函数的可读性和可维护性。

例如,下面是一个纯函数的例子:

// 纯函数,输入和输出类型明确
function add(a: number, b: number): number {
  return a + b;
}

函数式编程中纯函数的作用

在函数式编程中,纯函数具有非常重要的作用,因为它们是函数式编程的基础和核心概念之一。函数式编程的主要目标是尽可能地使用纯函数来组合构建程序,从而实现更加可靠、可维护和可重用的程序。

使用纯函数可以避免许多常见的编程问题,比如共享状态、副作用和不可变性等问题,从而提高程序的可靠性和稳定性。纯函数还可以使得程序更加容易进行测试和调试,因为它们具有确定性,可以轻松地对其进行单元测试和集成测试,而不必担心外部状态和上下文的影响。

纯函数还具有可缓存性和可移植性等优点,可以使得程序更加高效和灵活。通过缓存纯函数的结果,可以避免重复计算和提高程序的性能。通过将纯函数从程序中抽象出来,可以将其在不同的程序和环境中重复使用和测试,从而提高程序的可重用性和可维护性。

下面是一个简单的纯函数示例:

// 不是纯函数,因为修改了全局变量的值
let x = 10;
function impureAdd(y) {
  x += y;
  return x;
}

// 纯函数
function pureAdd(x, y) {
  return x + y;
}

在这个例子中,impureAdd 函数不是纯函数,因为它修改了全局变量 x 的值,因此它的行为不仅仅取决于它的参数 y,还取决于外部状态 x 的值。

相比之下,pureAdd 函数是纯函数,因为它不会改变任何外部状态,而且对于给定的输入 x 和 y,始终返回相同的结果。这使得 pureAdd 更容易测试和重用,因为它可以在任何时间,任何地点使用,并且不需要考虑外部环境的状态。