javascript-堆栈安全的相互递归,而不会在调用方泄漏实现细节

我对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

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...