我对clojure的循环/递归蹦床进行了广义化,以便可以与间接递归一起使用:
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
但是,我必须在通话侧明确给蹦床打电话.有没有办法像循环/递归那样再次使其隐式?
顺便说一句,这是循环/重复:
const loop = f => {
let acc = f();
while (acc && acc.type === recur)
acc = f(...acc.args);
return acc;
};
const recur = (...args) =>
({type: recur,args});
最佳答案
显然,由于您希望调用蹦床,因此不能完全跳过它.最简单的事情就是将那些经过抛光处理的调用包装在所需的API中,也许是这样的:
// Utility code
const trampoline = f => (...args) => {
let acc = f(...args);
while (acc && acc.type === recur) {
let [f,args});
// Private implementation
const _even = n =>
n === 0
? true
: recur(_odd,n - 1);
const _odd = n =>
n === 0
? false
: recur(_even,n - 1);
// Public API
const even = trampoline(_even);
const odd = trampoline(_odd);
// Demo code
console.log(
even (1e5 + 1)); // false
console.log(
odd (1e5 + 1)); // true
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。