函子与提升
函子怎样变换容器里的值?
- 函子(Functor): 提供
map,把普通函数作用于内部值,并保留外层结构; - 形式:
(A -> B) -> F<A> -> F<B>;
函子必须满足哪些定律?
- 恒等律:
fa.map(x => x)等价于fa; - 复合律:
fa.map(x => g(f(x)))等价于fa.map(f).map(g);
Some(1).map((x) => x); // Some(1)
const f = (x) => x + 1;
const g = (x) => x * 2;
Some(1).map((x) => g(f(x))); // Some(4)
Some(1).map(f).map(g); // Some(4)
Pointed Functor 多提供了什么?
- Pointed Functor: 提供
of,把任意单个普通值放入该函子; - 数组: ES2015 的
Array.of提供这一入口;
Array.of(1); // [1]
提升怎样让普通值或函数进入上下文?
- 提升值: 用
of把普通值放进函子; - 提升一元函数: 对函子使用后与
map等价; - 提升多元函数: 先柯里化,再通过应用函子的
ap逐个消费参数;
const liftA2 = (fn) => (fa, fb) => fa.map(fn).ap(fb);
const multiply = (a) => (b) => a * b;
liftA2(multiply)([1, 2], [3]); // [3, 6]
liftA2((a) => (b) => a + b)([1, 2], [30, 40]);
// [31, 41, 32, 42]
三个层级如何递进?
Functor:map 普通函数
↓ 增加 of
Pointed Functor:把普通值放入上下文
↓ 配合 ap
Applicative Functor:应用上下文中的函数