功能性JavaScript:关闭&递归。为什么这会失败?

时间:2018-02-19 19:05:41

标签: javascript recursion functional-programming

所需的功能:

mult(3);
 //(x) => 3 * mult(x)
mult(3)(4);
 //(x) => 3 * (4 * mult(x))
mult(3)(4)();
//12

尝试:

function mult(x){
    if(x === undefined){
        return 1;
    }else{
        return (y => x * mult(y));
    }
}

结果:

mult(3)
//y => x * mult(y)
//looks pretty good

mult(3)()
//3
//exactly what I want so far. 

mult(3)(4)()
//Uncaught TypeError: mult(...)(...) is not a function

果然,

mult(3)(4)
//NaN

然而mult(3)看起来不错,typeof mult(3) === "function"

是什么给出的? 我不能在JS中这么看中吗?为什么不呢?

3 个答案:

答案 0 :(得分:2)

mult(3)(4)

mult(3)会产生y => 3 * mult(y)

因此

(y => 3 * mult(y))(4)

变为

3 * mult(4)

mult(4)会产生y => 4 * mult(y)

3 * (y => 4 * mult(y))

是无稽之谈,因为您试图将3乘以函数。这就是您在此处获得NaN的原因,NaN无法进一步应用。

可能的解决方案:



function mkmult(acc) {
    return x =>
        x === undefined
            ? acc
            : mkmult(acc * x);
}

const mult = mkmult(1);

console.log(mult(3)());
console.log(mult(3)(4)());
console.log(mult(3)(4)(5)());




答案 1 :(得分:2)

如果您考虑一下,mult永远不应该通过undefined,因为它代表了当前的"或乘法的左侧。接收y的内部函数是应该处理提供结果的函数。



function mult(x){
    return y => {
        if (y === undefined) return x;
        else return mult(x * y);
    };
}

console.log(mult(3))
console.log(mult(3)())
console.log(mult(3)(4)())




答案 2 :(得分:2)

这是使用具有默认值

的辅助参数的另一种方法
  • 基本情况 - x未定义,返回累加器acc
  • 归纳案例 - x 未定义 - 返回一个新的lambda,要求下一个输入y并使用y和{{1}重复}

acc * x

就个人而言,我会使用已知的(显式)空值,而不是依赖于隐式const mult = (x, acc = 1) => x === undefined ? acc : y => mult (y, acc * x) console.log (mult ()) // 1 console.log (mult (2) ()) // 2 console.log (mult (2) (3) ()) // 6 console.log (mult (2) (3) (4) ()) // 24

undefined

实际上,上面定义的const Empty = Symbol () const mult = (x = Empty, acc = 1) => x === Empty ? acc : y => mult (y, acc * x) console.log (mult ()) // 1 console.log (mult (2) ()) // 2 console.log (mult (2) (3) ()) // 6 console.log (mult (2) (3) (4) ()) // 24是一个玩具。更实际的实现将使用可变参数接口而不是使用mult来判断返回值的奇怪的curirad

()