1. 函数柯里化
function curry(func) {
return function curriedFn(...args) {
if (args.length < func.length) {
return function () {
return curriedFn(...args.concat(Array.from(arguments)));
};
}
return func(...args);
};
}
2. 函数组合
function compose(...args) {
return function (value) {
return args.reverse().reduce(function (acc, fn) {
return fn(acc);
}, value);
};
}
3. 函子
- 容器:包含值和值的变形关系(这个变形关系就是函数)
- 函子:是一个特殊的容器,通过一个普通的对象来实现,该对象具有map方法,map方法可以进行一个蜀汉对值进行处理。
class Container {
static of (value) {
return new Container(value)
}
constructor (value) {
this._value = value
}
map (fn) {
return Container.of(fn(this._value))
}
}
let r = Container.of(5)
.map(x => x + 2)
.map(x => x * x)
总结:
- 函数式编程的运算不直接操作值,而是由函子来完成。
- 函子就是一个实现map的契约的对象
- 我们可以把函子想象成一个盒子,这个盒子装了一个值,想要处理盒子中的值,我们需要给盒子的map方法传递一个处理值的函数(纯函数),由这个函数对值进行处理
- 最终map方法返回一个包含新值的盒子(函子)
4. MayBe函子
解决空值问题
class MayBe {
static of(value) {
return new MayBe(value);
}
constructor(value) {
this._value = value;
}
map(fn) {
return this.isNothing() ? MayBe.of(null) : this.map(fn(this._value));
}
isNothing() {
return this._value === null || this._value === undefined;
}
}
5. Either函子
Either 函子
- Either两者中的任何一个。类似if ...else... 的处理
- 异常会让函数变得不纯,Either可以用来处理异常
class Left {
static of(value) {
return new Left(value);
}
constructor(value) {
this._value = value;
}
map(fn) {
return this;
}
}
class Right {
static of(value) {
return new Right(value);
}
constructor(value) {
this._value = value;
}
map(fn) {
return Right.of(fn(this._value));
}
}
const r1 = Right.of(12).map((x) => x + 2); //{ _value: 14 }
const l1 = Left.of(12).map((x) => x + 2); //{ _value: 12 }
function parseJSON(str) {
try {
return Right.of(JSON.parse(str));
} catch (err) {
return Left.of({ error: err.message });
}
}
const p = parseJSON("{name:kebe}");
//{ _value: { error: 'Unexpected token n in JSON at position 1' } }
const p1 = parseJSON('{"name":"kebe"}');
//{ _value: { name: 'kebe' } }
const p2 = parseJSON('{"name":"kebe"}').map((x) => x.toUpperCase());