什么是函数式编程?带示例的教程
什么是函数式编程?
函数式编程(也称为FP)是一种通过创建纯函数来思考软件构造的方式。它避免了面向对象编程中常见的共享状态和可变数据概念。
函数式语言强调表达式和声明,而不是语句的执行。因此,与其他依赖局部或全局状态的过程不同,FP中的值输出仅取决于传递给函数的参数。
函数式编程的特点
- 函数式编程方法侧重于结果,而非过程
- 强调计算的内容
- 数据是不可变的
- 函数式编程将问题分解为“函数”
- 它建立在数学函数概念之上,使用条件表达式和递归来执行计算
- 它不支持循环语句和 if-else 等条件语句的迭代
函数式编程的历史
- 函数式编程的基础是 lambda 演算。它在 20 世纪 30 年代为函数式应用、定义和递归而开发
- LISP 是第一门函数式编程语言。McCarthy 于 1960 年设计了它
- 在 70 年代末,爱丁堡大学的研究人员定义了 ML(元语言)
- 在 80 年代初,Hope 语言为递归和等式推理添加了代数数据类型
- 2004 年,函数式语言“Scala”创新。
函数式编程语言
任何 FP 语言的目标都是模仿数学函数。然而,函数式编程中的基本计算过程是不同的。
以下是一些最著名的函数式编程语言
- Haskell
- SML
- Clojure
- Scala
- Erlang
- Clean
- F#
- ML/OCaml Lisp / Scheme
- XSLT
- SQL
- Mathematica
函数式编程基本术语和概念
不可变数据
不可变数据意味着您应该能够轻松创建数据结构,而不是修改已存在的数据结构。
引用透明性
函数式程序应像第一次一样执行操作。因此,您将知道程序执行期间可能发生或未发生的情况及其副作用。在 FP 术语中,这称为引用透明性。
模块化
模块化设计可提高生产力。小型模块可以快速编写代码,并且具有更大的重用机会,这肯定会导致更快的程序开发。此外,模块可以单独测试,这有助于减少单元测试和调试所花费的时间。
可维护性
可维护性是一个简单的术语,意味着 FP 编程更容易维护,因为您无需担心意外更改函数外部的任何内容。
头等函数
“头等函数”是对编程语言实体的一种定义,这些实体在使用上没有任何限制。因此,头等函数可以在程序的任何地方出现。
结案
闭包是内部函数,即使父函数已执行,它也可以访问父函数的变量。
高阶函数
高阶函数要么将其他函数作为参数,要么将它们作为结果返回。
高阶函数支持部分应用或柯里化。这种技术将函数一次应用于其参数,每次应用都会返回一个接受下一个参数的新函数。
纯函数
“纯函数”是输入被声明为输入的函数,其中任何一个都不应隐藏。输出也被声明为输出。
纯函数作用于其参数。如果不返回任何内容,则效率不高。此外,它为给定的参数提供相同的输出
示例
Function Pure(a,b) { return a+b; }
非纯函数
非纯函数正好与纯函数相反。它们具有隐藏的输入或输出;这称为非纯。非纯函数由于存在依赖关系,因此无法单独使用或测试。
示例
int z; function notPure(){ z = z+10; }
函数组合
函数组合是通过组合 2 个或多个函数来创建一个新函数。
共享状态
共享状态是 OOP 编程中的一个重要概念。基本上,它是向对象添加属性。例如,如果 HardDisk 是一个对象,则可以添加存储容量和磁盘大小作为属性。
副作用
副作用是发生在被调用函数外部的任何状态更改。任何 FP 编程语言的最大目标是通过将其与软件代码的其余部分分离来最小化副作用。在 FP 编程中,将副作用与您的其余编程逻辑分开至关重要。
函数式编程的好处
- 使您能够避免代码中令人困惑的问题和错误
- 更容易测试和执行单元测试以及调试 FP 代码。
- 并行处理和并发
- 热代码部署和容错
- 提供更好的模块化和更少的代码
- 提高开发人员的生产力
- 支持嵌套函数
- 函数式构造,如惰性 Map & 列表等
- 允许有效使用 Lambda 演算
函数式编程的局限性
- 函数式编程范例不容易,因此初学者难以理解
- 维护困难,因为许多对象在编码过程中会发生变化
- 需要大量模拟和广泛的环境设置
- 重用非常复杂,需要不断重构
- 对象可能无法正确表示问题
函数式编程与面向对象编程
函数式编程 | OOP |
---|---|
FP 使用不可变数据。 | OOP 使用可变数据。 |
遵循声明式编程模型。 | 遵循命令式编程模型。 |
它关注的是:“你在程序中做什么。” | 它关注的是“你如何进行编程。” |
支持并行编程。 | 不支持并行编程。 |
其函数没有副作用。 | 方法会产生许多副作用。 |
流程控制通过函数调用和递归函数调用来执行。 | 流程控制过程通过循环和条件语句进行。 |
语句的执行顺序不太重要。 | 语句的执行顺序很重要。 |
支持“数据抽象”和“行为抽象”。 | 仅支持“数据抽象”。 |
结论
- 函数式编程或 FP 是一种基于一些基本定义原则来思考软件构造的方式
- 函数式编程概念侧重于结果,而非过程
- 任何 FP 语言的目标都是模仿数学函数
- 一些最著名的函数式编程语言:1) Haskell 2) SM 3) Clojure 4) Scala 5) Erlang 6) Clean
- “纯函数”是输入被声明为输入的函数,其中任何一个都不应隐藏。输出也被声明为输出。
- 不可变数据意味着您应该能够轻松创建数据结构,而不是修改已存在的数据结构
- 使您能够避免代码中令人困惑的问题和错误
- 函数式代码不易理解,对初学者来说很难
- FP 使用不可变数据,而 OOP 使用可变数据