我正在尝试使用函数式的List
类型和结构共享。由于Javascript没有尾递归模除法优化,因此我们不能像这样编写List
组合器,因为它们不是堆栈安全的:
const list =
[1, [2, [3, [4, [5, []]]]]];
const take = n => ([head, tail]) =>
n === 0 ? []
: head === undefined ? []
: [head, take(n - 1) (tail)];
console.log(
take(3) (list) // [1, [2, [3, []]]]
);
现在我尝试使用尾递归实现take
函数,这样我就可以依靠TCO(在Ecmascript中仍然是一个未解决的Promise
)或使用跳转器(为了保持简单,在示例中省略):
const list =
[1, [2, [3, [4, [5, []]]]]];
const safeTake = n => list => {
const aux = (n, acc, [head, tail]) => n === 0 ? acc
: head === undefined ? acc
: aux(n - 1, [head, acc], tail);
return aux(n, [], list);
};
console.log(
safeTake(3) (list) // [3, [2, [1, []]]]
);
这个方法可行,但是新创建的列表是反向排序的。我该如何以纯函数式的方式解决这个问题呢?
safeTake
中返回reverse(aux(n, [], list))
。 - BergiList
类型:D - user6445533