如何防止尾递归函数反转 List 的顺序?

5 javascript recursion functional-programming tail-recursion

我正在试验功能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, []]]]
);
Run Code Online (Sandbox Code Playgroud)

现在我尝试take递归地实现尾部,以便我可以依赖 TCO(Promise在 Ecmascript 中仍然未解决)或使用蹦床(在示例中省略以保持简单):

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, []]]]
);
Run Code Online (Sandbox Code Playgroud)

这有效,但新创建的列表顺序相反。我怎样才能以纯功能的方式解决这个问题?