Lean 函数式编程

5. 函子、应用函子与单子

FunctorMonad 都描述了针对仍在等待一个类型参数的类型的操作。 理解它们的一种方式是:Functor 描述其中所含数据可以被变换的容器,而 Monad 描述带有副作用的程序的一种编码。 然而,这种理解并不完整。 毕竟,Option 同时具有 FunctorMonad 的实例,并且同时表示一个可选值 and 一个可能无法返回值的计算。

从数据结构的角度看,Option 有些像可空类型,或像至多只能包含一个条目的列表。 从控制结构的角度看,Option 表示一种可能在没有结果的情况下提前终止的计算。 通常,使用 Functor 实例的程序最容易被理解为把 Option 用作数据结构,而使用 Monad 实例的程序最容易被理解为使用 Option 来允许提前失败;不过,学会熟练运用这两种视角,是精通函数式编程的重要组成部分。

函子与单子之间存在更深层的关系。 事实证明,每个单子都是函子。 另一种说法是,单子抽象比函子抽象更强大,因为并非每个函子都是单子。 此外,还存在一种额外的中间抽象,称为应用函子,它具有足够的表达能力来编写许多有趣的程序,同时又允许使用无法采用 Monad 接口的库。 类型类 Applicative 提供了应用函子的可重载操作。 每个单子都是应用函子,每个应用函子都是函子,但反过来并不成立。

  1. 5.1. 结构与继承
  2. 5.2. 应用函子
  3. 5.3. 应用函子约定
  4. 5.4. 选择
  5. 5.5. 宇宙
  6. 5.6. 完整定义
  7. 5.7. 小结