Functor 函子
1. 作用
控制副作用,异常处理,异步操作
副作用是指: 让函数变得不纯的因素
2. 什么是函子:
函子是一个对象
函子是一个容器: 值(对内) + 处理值的函数map(fn)(对外)
map(fn)参数:一个对值进行操作的函数
3. 手写 Functor
#3.1 ’new‘关键词
class Container {
constructor(value){ // 函子内部维护的值, 只有函子自己知道
this._value = value // _.value, 私有成员,不希望外部访问
}
// map方法 :接受处理值得函数,并返回一个新的函子,将处理得到的值传入其中//
map(fn) { // 对外公布的方法 map ,接受一个函数参数
return Container.of (fn(this._value)) // return 一个新的函子对象 而不是 “值”
}
}
#3.2 使用 静态方法 of 封装 ’new‘ 关键词
class Container {
static of (value){ // static 创建静态方法, 方法名为 of
return new Container(value) // 返回一个函子对象
}
constructor(value){ // 函子内部维护的值, 只有函子自己知道
this._value = value // _.value, 私有成员,不希望外部访问
}
map(fn) { // 对外公布的方法 map ,接受一个函数参数
return Container.of (fn(this._value)) // return 一个新的函子对象 而不是 “值”
}
}
#4. 调用手写 functor
let r = Container.of(5) //创建一个新的函子(传入一个值)
.map( x => x+5) //调用functor的 map(fn)方法,传入一个处理值得函数
.map(x=>x*x) //使用map(fn)链式调用
console.log(r); //返回结果 Container {_value:36}
Maybe Functor函子
1.作用:
控制外部空值得传入
2.手写:
建立在functor之上 + isNothing()方法 判断传入值是否为 null or undefiend 、如果传入”空“,返回一个值为”空的函子“,如果传入有效值,则如普通函子
class Container {
static of (value){ // static 创建静态方法, 方法名为 of
return new Container(value) // 返回一个函子对象
}
constructor(value){ // 函子内部维护的值, 只有函子自己知道
this._value = value // _.value, 私有成员,不希望外部访问
}
map(fn) { // 对外公布的方法 map ,接受一个函数参数
return this.isNothing()?Maybe.of(null) : Maybe(fn(this._value))
// return 一个新的函子对象 (看情况返回)
}
isNothing(){
return this._value === null || this._value === undefined
}
}
调查 :
A ? B: C
A && B
A || B
问题:如果多次调用map(),无法判断哪一个map()出现了问题 , either 可以解决
Either Functor函子
其实和Maybe函子差不多,只不过将判断包装在外部函数中,将Maybe函子拆分成两个不同的函子分别处理不同的情况 Maybe 函子通过 isNothing()方法来判断
//返回原来的函子
class Left {
static of(value){
new Left(value)
}
constructor (value){
this._value = value
}
map(fn){
return this
}
}
//返回处理过值的函子
class Right {
static of(value){
new Right(value)
}
constructor (value){
this._value = value
}
map(fn){
return new Right.of(fn(this._value)
}
}
//将两个函子的调用放入一个函数中
function parseJson(str){
try{
return Right(JSON.parse(str))
}catch(e){
return Left.of({error: e.message})
}
}
IO 函子 INPUT OUTPUT
const fp = require('lodash/fp')
class IO {
static of (value) { //接受数据/ 返回一个函子
return new IO(function () { //返回的函子:接受一个函数 返回接受的原始数据
return value //返回一开始输入的数据
})
}
constructor (fn) { //IO函子保留的是函数,因此创建时,输入的是value是函数
this._value = fn
}
map (fn) { // 输入一个函数/ 返回一个新的函子/
return new IO(fp.flowRight(fn, this._value))
}
}
调用
let r = IO.of(process).map(p => p.execPath) // r 是一个包裹着函数值得函子,r._value 就是这个函数
console.log(r) // 函子
console.log(r._value()) // 函子中包裹的函数(这里面有需要处理的值,直接调用就好)
// 组合函数中的第一个函数将值原样返回
IO.of(value)利用IO函子的静态方法of将数据包裹在函数里,再用这个函数作为参数创建一个IO函子,这里用的是new 关键词创建,
包裹value的函数被赋予this._value,此时 this.value 是 一个 function,包裹着 process创建了一个新的函子