如何在ES6中讨论递归函数

时间:2017-11-02 22:20:52

标签: javascript ecmascript-6 functional-programming currying

我正在使用javascript lambda表达式进行一些函数式编程实践,并提出了以下代码。该代码旨在返回一个函数,该函数计算给定基数值的给定数量的幂。我的代码如下;

const findUpper = base => (num, i = 0) => {
  if (num < base) {
    return i;
  } else {
    i++;
    return findUpper(Math.round(num / base), i);
  }
}

const findUpper2 = findUpper(2)
console.log(findUpper2(8)) //expected to have 3

这里的问题是,在第一次findUpper调用后,递归会被破坏,因为它会返回一个函数。

如何使此代码段有效?

2 个答案:

答案 0 :(得分:2)

一种方式就是这样

    var findUpper = base => {
        let fn = (num, i = 0) => {
            if (num < base) {
                return i;
            } else {
                i++;
                return fn(Math.round(num / base), i);
            }
        };
        return fn;
    }
    var findUpper2 = findUpper(2)
    console.log(findUpper2(8))

使用bothUpper中的名称声明递归函数...递归调用fn而不是findUpper

如果没有不必要地使用箭头功能,它会稍微“整洁”

var findUpper = base => {
    return function fn(num, i = 0) {
        if (num < base) {
            return i;
        } else {
            i++;
            return fn(Math.round(num / base), i);
        }
    };
}
var findUpper2 = findUpper(2)
console.log(findUpper2(8))

虽然,使用=&gt;代码可以像

一样简单
const findUpper = base => {
    let fn = (num, i = 0) => (num < base) ? i : fn(Math.round(num / base), i + 1);
    return fn;
}

答案 1 :(得分:0)

这是你的错误

i++
return findUpper(Math.round(num / base), i);

您打算:

// don't forget, findUpper is a curried function
return findUpper(Math.round(num/base))(i + 1);

这是将程序编写为纯表达式的另一种方法

&#13;
&#13;
const findUpper = (base = 1) => (num = 0, exp = 0) =>
  num < base
    ? exp
    : findUpper (base) (num / base, exp + 1)
    
console.log (findUpper (2) (8))
&#13;
&#13;
&#13;

使用通用的loop / recur程序,我们保持findUpper的参数清洁,提高循环性能,并维护您想要的咖喱界面

&#13;
&#13;
const recur = (...values) =>
  ({ recur, values })
  
const loop = f =>
{
  let acc = f ()
  while (acc && acc.recur === recur)
    acc = f (...acc.values)
  return acc
}

const findUpper = (base = 1) => (num = 0) =>
  loop ((n = num, exp = 0) =>
    n < base
      ? exp
      : recur (n / base, exp + 1))

console.log (findUpper (2) (8))
&#13;
&#13;
&#13;