递归模式
Catamorphism 怎样把结构折叠成值?
- Catamorphism: 逐步拆解结构并归约为一个值;
- 数组中的例子:
reduceRight;
const sum = (xs) => xs.reduceRight((acc, x) => acc + x, 0);
sum([1, 2, 3, 4, 5]); // 15
Anamorphism 怎样从种子展开结构?
- Anamorphism: 反复对种子应用生成函数,逐步构造结构;
unfold: 返回[当前值, 下一个种子],无结果时停止;
const unfold = (fn, seed, result = []) => {
const next = fn(seed);
return next ? unfold(fn, next[1], [...result, next[0]]) : result;
};
const countDown = (n) => unfold((x) => (x <= 0 ? undefined : [x, x - 1]), n);
countDown(5); // [5, 4, 3, 2, 1]
Hylomorphism 怎样连接展开与折叠?
- Hylomorphism: 先用 Anamorphism 构造结构,再用 Catamorphism 消解结构;
const sumUpTo = (n) => sum(countDown(n));
sumUpTo(5); // 15
Paramorphism 比普通折叠多知道什么?
- Paramorphism: 归约器同时拿到当前元素、剩余原始结构和递归结果;
- 差异: Catamorphism 只消费归约结果;Paramorphism 还能查看形成结果的历史结构;
const para = (reducer, initial, elements) => {
if (!elements.length) return initial;
const [head, ...tail] = elements;
return reducer(head, tail, para(reducer, initial, tail));
};
const suffixes = (xs) => para((_x, tail, rest) => [tail, ...rest], [], xs);
suffixes([1, 2, 3]); // [[2, 3], [3], []]
Apomorphism 怎样让展开提前结束?
- Apomorphism: Paramorphism 的对偶,如同 Anamorphism 是 Catamorphism 的对偶;
- 能力: 展开结构时既能继续生成,也能直接返回已经完成的剩余结构;
五种模式怎样对应?
| 模式 | 方向 | 额外能力 |
|---|---|---|
| Catamorphism | 结构 → 值 | 折叠 |
| Anamorphism | 种子 → 结构 | 展开 |
| Hylomorphism | 展开后折叠 | 组合前两者 |
| Paramorphism | 结构 → 值 | 折叠时保留原结构历史 |
| Apomorphism | 种子 → 结构 | 展开时允许提前返回结构 |