Я обобщил батут Clojure loop
/ recur
так, чтобы он работал с косвенной рекурсией:
const trampoline = f => (...args) => {
let acc = f(...args);
while (acc && acc.type === recur) {
let [f, ...args_] = acc.args;
acc = f(...args_);
}
return acc;
};
const recur = (...args) =>
({type: recur, args});
const even = n =>
n === 0
? true
: recur(odd, n - 1);
const odd = n =>
n === 0
? false
: recur(even, n - 1);
console.log(
trampoline(even) (1e5 + 1)); // false
Тем не менее, я должен позвонить на батуте явно на стороне вызова. Есть ли способ сделать это снова неявным, как с loop
/ recur
?
Кстати, здесь loop
/ recur
:
const loop = f => {
let acc = f();
while (acc && acc.type === recur)
acc = f(...acc.args);
return acc;
};
const recur = (...args) =>
({type: recur, args});