折叠与遍历
Foldable 怎样把多个元素归约成一个值?
- Foldable: 提供
reduce,按顺序把累加器与每个元素结合; - 结果: 一个汇总值,不再保留原集合形状;
const sum = (xs) => xs.reduce((acc, value) => acc + value, 0);
sum([1, 2, 3]); // 6
Traversable 怎样把内外两层结构翻转?
- Traversable: 同时具备 Foldable 与 Functor 能力;
sequence/traverse: 把F<G<A>>变为G<F<A>>;- 场景: 把一组 Promise 变成一个包含整组结果的 Promise,或把可选性移到集合外;
[Promise<A>, Promise<B>] -> Promise<[A, B]>
const promiseSequence = (promises) =>
promises.reduce(
(acc, promise) => acc.then((values) => promise.then((value) => [...values, value])),
Promise.resolve([]),
);
promiseSequence([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]).then(console.log); // [1, 2, 3]
sequence 与 traverse 有什么关系?
sequence: 输入已经是“容器里的上下文值”,只翻转结构;traverse: 先用函数把普通元素变成上下文值,再完成sequence;- 直观关系:
traverse(fn, xs) = sequence(xs.map(fn));
Foldable、Functor 与 Traversable 怎样分工?
| 结构 | 关注点 |
|---|---|
| Functor | 保持外形并变换内部值 |
| Foldable | 消解外形并汇总为一个结果 |
| Traversable | 保持外形,同时把效果移到外层 |