函数式编程专业术语
学习函数式编程的基础概念和专业名词。
Arity
函数参数个数,带有两个参数的函数被称为二元函数arity值为2。
高阶函数(Higher-Order Function / HOF)
以函数为参数或/和返回值。
偏函数(Partial Function)
对原始函数预设参数作为一个新的函数。
//创建偏函数,固定一些参数
const partical = (f, others) =>
//返回带有剩余参数的函数
(...moreArgs) =>
//调用原始函数
f(...ars, ...moreArgs)
//调用
const add = (a,b,c) => a+b+c;
const fivePlus = partical(add, 2,3);
fivePlus(4)
也可以使用bind实现偏函数。
const addMore = add.bind(null, 2,3);
偏函数应用通过对复杂的函数填充一部分数据来构成一个简单的函数,柯里化通过偏函数实现。
柯里化 (Currying)
将一个多元函数转变为一元函数的过程,每当函数被调用时,它仅仅接收一个参数并且返回带有一个参数的函数,直到传递完所有的参数。
loadsh,understore,remda,curry 都可以自动完成柯里化。
函数组合(Function Composing)
接受多个函数作为参数,从右到左,一个函数的输入为另一个函数的输出。
纯函数(Purity)
输入仅由输出决定,不产生副作用。
副作用(Side effect)
如果函数与外部可变状态进行交互,则它是有副作用的,简单来说就是不使用全局变量。
幂等性(Idempotent)
如果一个函数执行多次返回相同的结果,说明它是幂等性的。
Point-Free风格(Point-Free Style)
定义函数时,不显式地指出函数所带参数,这种风格需要柯里化或者高阶函数来实现。
谓词(Predicate)
根据输入返回true或false,通常在Array.prototype.filter的回调函数中使用。
契约(Contracts)
契约保证了函数或者表达式在运行时的行为,当违反契约时将抛出一个错误。
范畴(Category)
范畴论中,范畴是指对象集合及他们之间的态射,在编程中,数据类型作为对象,函数作为态射。
一个有效的范畴遵从以下三个原则。
- 必有一个identiry态射,使得map一个对象是它自身,a是范畴里的一个对象时,必须有一个函数使a -> a。
- 态射必是可组合的,a,b,c是范畴里的对象,f是态射a -> b,g是b->c态射。g(f(x))一定与(g*f)(x)是等价的。
- 组合满足结合律。f(gh)与(fg)h是等价的。
值(value)
赋值给变量的值称为Value。
常量(Constant)
一旦定义不可重新赋值。
函子(Functor)
一个实现了map函数的对象,map会遍历对象中的每个值并生成一个新的对象。遵守两个准则。
- 一致性(Preserves identity)
- 组合性(Composable)
Pointed Functor
一个实现了of函数的对象,ES2015添加了Array.of,使得Array成为了Pointed Functor。
引用透明性(Referential Transparency)
一个表达式能够被它的值替代而不改变程序的行为称为引用透明。
匿名函数(Lambda)
匿名函数被视作一个值,匿名函数通常作为高阶函数的参数,也可以把lambda赋值给一遍变量。
惰性求值(Lazy evaluation)
按需求值机制,只有当需要计算所得值时才会计算
Moniod
一个对象拥有一个函数用来连接相同类型的对象
需要满足结合律
数值的加法就是一个简单的Monoid
1+1 //2
如上示例,数值是对象而 +是函数
与另一个值结合而不会改变它的值,称为identity,加法的identity值为0
数组的结合也是Monoid,identity值为空的数组
identiry与compose函数能够组成monoid
Monad
拥有of和chain函数的对象,chain和map类似,除了可以用来铺平嵌套数据
Array.prototype.chain = function (f) {
return this.reduce((acc, it) => acc.concat(f(it)), [])
}
// ['cat', 'dog', 'fish', 'bird']
;Array.of('cat,dog', 'fish,bird').chain(s => s.split(','))
// [['cat', 'dog'], ['fish', 'bird']]
;Array.of('cat,dog', 'fish,bird').map(s => s.split(','))
在有些语言中,of 也称为 return,chain 也称为 flatmap 与 bind。
Comonad
拥有extract与extend函数的对象
const CoIdentity = (v) => ({
val: v,
extract () {
return this.val
},
extend (f) {
return CoIdentity(f(this))
}
})
CoIdentity(1).extract()
CoIdentity(1).extend(x => x.extract() + 1) # CoIdentity(2)
Applicative Functor
拥有ap函数的对象
//实现
Array.prototype.ap = function(xs){
return this.reduce((acc, f) => acc.concat(xs.map(f)), []))
}
态射(Morphism)
一个变形的函数
自同态(Endomorphism)
输入输出是相同类型的函数
同构(Isomorphism)
不同类型对象的变形,保持结构并且不丢失数据
例如二维坐标既可以表示为数组[1,2]也可以标识为对象{x:2,y:3}
Setoid
拥有equals函数的对象,equals可以用来和其他对象比较
半群(Semigroup)
一个拥有concat函数的对象。concat可以连接相同类型的两个对象
Foldable
一个拥有reduce函数的对象,reduce可以把一种类型的对象转化为另一种类型
类型签名(Type Signatures)
通常js会在注释中指出参数和返回值的类型
联合类型
连接不同的数据类型
推荐库
- union-type
- daggy
Product type
用一种更熟悉的方法把数据类型联合起来
Option
Option 是一种联合类型,它有两种情况,Some 或者 None。