【问题标题】:How to make a function call itself n times如何让函数调用自己 n 次
【发布时间】:2020-08-25 23:32:11
【问题描述】:

假设我有一个名为 f 的函数,它接受一个名为 x 的整数参数并返回一个整数。我还有一个整数 n 表示函数必须调用自身多少次。因此,例如,如果我的函数调用在 n = 1 时看起来像这样 f(x),那么当 n = 3 时它看起来像这样 f(f(f(x)))。在下面的示例中怎么会这样:

function succ(n) {
  return function (f, x) {
    return f(x);
  };
}

【问题讨论】:

  • f 的论点我摸不着。

标签: javascript function functional-programming currying church-encoding


【解决方案1】:

您可以构建一个times 高阶函数并使用它来包装其他函数...

const times = (fn, n) => (...args) => {
  if (!n) { return; }
  
  fn(...args);
  
  return times(fn, n - 1)(...args);
}

const log10 = times(console.log, 10);

log10('hello');

【讨论】:

    【解决方案2】:

    我们可以核心递归地表达这个算法。 Corecursion 从起点开始在前进的道路上构建它的结果:

    const iterate = f => x =>
      [x, () => iterate(f) (f(x))];
    
    const main = iterate(x => x * 2) (1);
    
    console.log(
      main[1] () [1] () [1] () [1] () [1] () [1] () [1] () [1] () [0]); // 256

    这只是一个概念证明,而不是我们真正想要的。我们如何避免笨拙的界面?我们可以使用Proxy 使非参数函数隐含。它与惰性属性 getter 的机制基本相同。此外,我们不想手动访问流中的值,而是使用方便的函数:

    class ThunkProxy {
      constructor(f) {
        this.memo = undefined;
      }
    
      get(g, k) {
        if (this.memo === undefined)
          this.memo = g();
    
        if (k === THUNK)
          return true;
    
        else if (k === Symbol.toPrimitive)
          return () => this.memo;
    
        else if (k === "valueOf")
          return () => this.memo;
    
        else return this.memo[k];
      }
    }
    
    const THUNK = "thunk";
    
    const thunk = f =>
      new Proxy(f, new ThunkProxy(f));
    
    const iterate = f => x =>
      [x, thunk(() => iterate(f) (f(x)))];
    
    const takeNth = n => ([head, tail]) =>
      n === 0
        ? head
        : takeNth(n - 1) (tail);
        
    const main = iterate(x => x * 2) (1);
    
    console.log(
      main[1] [1] [1] [1] [1] [1] [1] [1] [0]); // 256
    
    console.log(
      takeNth(16) (main)); // 65536

    【讨论】:

      【解决方案3】:

      你可以在内部函数中循环:

       for(let i = 0; i < n; i++) x = f(x);
       return x;
      

      或者让你的函数自己调用:

       return n > 0 ? succ(n - 1)(f, f(x)) : x;
      

      【讨论】:

      • 就是这么简单。我怎么没想到呢。
      猜你喜欢
      • 1970-01-01
      • 2016-12-16
      • 1970-01-01
      • 2023-03-16
      • 2020-01-18
      • 2022-01-09
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多