简体   繁体   English

如何让 function 调用自身 n 次

[英]How to make a function call itself n times

Let's say I have a function called f that takes an integer argument called x and returns an integer.假设我有一个名为 f 的 function,它接受一个名为 x 的 integer 参数并返回一个 integer。 I also have an integer n that says how many times the function must call itself.我还有一个 integer n 表示 function 必须调用自己多少次。 So for example if my function call looks like this f(x) when n = 1, then it would look like this f(f(f(x))) when n = 3. How could something like that look in my example bellow:因此,例如,如果我的 function 调用在 n = 1 时看起来像这样f(x) ,那么当 n = 3 时它看起来像这样f(f(f(x))) 。在我下面的示例中怎么会这样:

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

You could loop inside the inner function:您可以在内部 function 内循环:

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

or alternatively let your function call itself:或者让您的 function 自己调用:

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

We can express this algorithm corecursively.我们可以核心递归地表达这个算法。 Corecursion builds its result on the way forward from the starting point: 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

This is just a proof of concept but not what we actually want.这只是一个概念证明,而不是我们真正想要的。 How can we avoid the clunky interface?我们如何避免笨拙的界面? We can use a Proxy to make the non-argument function implicit.我们可以使用Proxy来使非参数 function 隐含。 It is basically the same mechanism as with lazy property getters.它与惰性属性 getter 的机制基本相同。 Additionally we don't want to access values from the stream manually but with a function for convenience:此外,为了方便,我们不想手动访问 stream 中的值,而是使用 function :

 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

You could build a times high order function and use it to wrap other functions...您可以构建一个高阶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');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM