函数式编程(Functional programming)

简单,可测试,可以重复

  • 与面向对象编程(Object-oriented programming)和过程式编程(Procedural programming)并列的编程范式。
  • 最主要的特征是,函数是第一等公民
  • 强调将计算过程分解成可复用的函数,典型例子就是 map 方法和 reduce 方法组合而成 MapReduce 算法
  • 只有纯的、没有副作用的函数,才是合格的函数。

  • 闭包
  • 高阶函数
  • 柯里化/自动柯里化
  • lambda 演算
  • 副效果
  • 纯函数
  • 幂等
  • Partial Application
  • Referential Transparency
  • 函数组合
  • 谓词:返回真或假的函数
  • Contracts:违反合同时报告错误
  • 范畴论

函数式编程有两个最基本的运算:合成和柯里化。
compose(f, compose(g, h))
// 等同于
compose(compose(f, g), h)
// 等同于
compose(f, g, h)

f(x)和g(x)合成为f(g(x)),有一个隐藏的前提,就是 f 和 g 都只能接受一个参数。
"柯里化",就是把一个多参数的函数,转化为单参数函数。// fn.length 能得到参数个数
局部应用(偏函数)则是固定一个函数的一个或者多个参数,也就是将一个 n 元函数转换成一个 n - x 元函数。

函数不仅可以用于同一个范畴之中值的转换,还可以用于将一个范畴转成另一个范畴。这就涉及到了函子(Functor)。它首先是一种范畴,也就是说,是一个容器,包含了值和变形关系。比较特殊的是,它的变形关系可以依次作用于每一个值,将当前容器变形成另一个容器。任何具有map方法的数据结构,都可以当作函子的实现。

学习函数式编程,实际上就是学习函子的各种运算。

Maybe 函子的map方法里面设置了空值检查。
Either 函子内部有两个值:左值(Left)和右值(Right)。右值是正常情况下使用的值,左值是右值不存在时使用的默认值。另一个用途是代替try...catch,使用左值表示错误
ap 是 applicative 的缩写。凡是部署了ap方法的函子,就是 ap 函子。让函子B内部的函数,可以使用函子A内部的值进行运算,ap 函子的意义在于,对于那些多参数的函数,就可以从多个容器之中取值,实现函子的链式操作。
Monad 函子的作用是,总是返回一个单层的函子。Monad 函子的重要应用,就是实现 I/O (输入输出)操作。它的 flatMap方法被改名成chain。

范畴:
函数式编程的起源,是一门叫做范畴论(Category Theory)的数学分支
范畴论认为世界上所有的概念体系,都可以抽象成一个个的"范畴"(category)
"范畴就是使用箭头连接的物体。"(In mathematics, a category is an algebraic structure that comprises "objects" that are linked by "arrows". )
箭头表示范畴成员之间的关系,正式的名称叫做"态射"(morphism)

数学模型:
  • 所有成员是一个集合
  • 变形关系是函数