Я экспериментирую с функциональным типом List
и структурным разделением.Поскольку в Javascript нет оптимизации Tail Recursive Modulo Cons , мы не можем просто написать 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
tail, чтобы я мог либо полагаться на 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, []]]]
);
Это работает, но новый созданный список находится в обратном порядке.Как я могу решить эту проблему чисто функциональным образом?