'Javascript Recursive Function Currying and Arrow Functions

This is fine and works:

const power = (x,n) => {
  if (n === 0) return 1;
  return x * power(x, n - 1);
}

power(4,3) 64

But trying to do this as experiment - does not work gives NaN Do not understand why:

node .editor // Entering editor mode (Ctrl+D to finish, Ctrl+C to cancel)

const power = x => {
  return n => {
    if (n === 0) return 1;
    return x * power(x, n - 1);
  }
}

let t = power(4) t(3) NaN



Solution 1:[1]

You haven't converted the recursive call in the curried version to curried form. power(x, n - 1) is essentially the same as power(x) because power only accepts one argument, and this is a function, so not unreasonably becomes NaN when you try to multiply it by a number.

Rewrite it like this instead:

const power = x => {
  return n => {
    if (n === 0) return 1;
    return x * power(x)(n - 1);
  }
};

console.log('4^3 = ', power(4)(3));     // 64
console.log('2^10 = ', power(2)(10));   // 1024
console.log('5^4 = ', power(5)(4));     // 625
console.log('3^4 = ', power(3)(4));     // 81

Solution 2:[2]

You could store the nested function and return the function and use this function for another call with only the changed n.

const
    power = x => {
        const
            fn = n => n === 0
                ? 1
                : x * fn(n - 1);

        return fn;
    };

console.log(power(4)(3));

Solution 3:[3]

As we are discussing "weird" function forms I might as well contribute my two cents worth:

You can also do the curried function as a one-liner like this:

const power = (x,pow) => pow = n => --n ? x*pow(n) : x;

console.log(power(3)(4)); // 81

This is, of course, something that nobody in their right mind would ever do. Still - it works!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jsN00b
Solution 2 Nina Scholz
Solution 3