4

I'm trying to write a sum function that does the following:

sum(1)(2)(3) => returns 6

However, I am having hard time with my solution. I know i'm making a silly mistake, can someone point me in the right direction?

My Implementation:

function add(args) {
  let sum = args[0];
  let func = function(...args2) {
    if (!args2[0]) return sum;
    sum += args2[0];
    return func;
  }
  return func;
}


add(1)(2)(3);

Additionally, can I write a generic function that does the following? add(1)(2)(3) or add (1)(2)(3) () => 6

vol7ron
  • 40,809
  • 21
  • 119
  • 172
TechnoCorner
  • 4,879
  • 10
  • 43
  • 81
  • Is it supposed to take arbitrary numbers of arguments? You can’t have both `add(1)(2) === 3` and `add(1)(2)(3) === 6`, but `add(1)(2)() === 3` and `add(1)(2)(3)() === 6` is possible (and, I think, what your code already does, by trying to check for `undefined` with `if(!args2[0])` – although that won’t work for 0). – Ry- Sep 01 '18 at 02:40
  • 1
    Try `const add = a => b => c => a + b + c;` – CertainPerformance Sep 01 '18 at 02:40
  • 1
    https://stackoverflow.com/a/25578965/5648253 – Helping hand Sep 01 '18 at 05:13
  • 1
    Currying is a novelty. Just as you've had difficulty in constructing it, others will have a difficulty in maintaining it. Best advice is to stay away from it if you can. – vol7ron Sep 01 '18 at 15:14

4 Answers4

5

To have an arbitrary amount of calls, all which take a number, you'd need the return value to behave both as a function and a number depending. So that:

const five = add(2)(3);
console.log(five(10)); // behaves like a function
console.log(five + 10); // behaves like a number

I can't think of anyway to do that (or if there's a good reason one should do that) other than what I'd call a hack.



With that said, for fun I was able to do the following by abusing valueOf():

const add = (num1) => {
  const func = (num2) => add(num1 + num2);
  func.valueOf = () => num1;

  return func;
}

console.log(add(1)(2)(3)); // *logs function* [output varies by environment]

console.log(add(1)(2)(3) + 10);  // 16
console.log(add(1)(2) + 10);  // 13
console.log(add(1) + 10);  // 11

console.log(add(1)(2)(3) == 6); // true
console.log(add(1)(2)(3) === 6); // false

console.log(typeof add(1)(2)(3)); // function
console.log(typeof (add(1)(2) + 3)); // number

But that's obviously not very kosher.


Edit: Switched from using toString() to valueOf() per @PatrickRoberts's comment.

SamVK
  • 3,077
  • 1
  • 14
  • 19
1

Recursion anyone?

function add(n) {
  return function(m) {
    if (isNaN(m)) return n;
    return add(n + m);
  };
}

// add(1)(2)(3)() => 6
// add(1)(2)(3)("")() => "6"
// add(1)("2")(3)() => "123"

// functional one liner
const add = n => m => isNaN(m) ? n : add(n + m);
wmik
  • 734
  • 10
  • 23
0

Try this, you omitted the spread operator

function add(...args) {
        let sum = args[0];
        let func = function(...args2) {
            if(args2[0] === undefined) return sum;
            sum += args2[0];
            return func;
        }
        return func;
    }
    
    
    console.log(add(1)(2)(3)());

cheers!!

Ewomazino Ukah
  • 2,286
  • 4
  • 24
  • 40
0
function sum(x){
   return function (y){
      return function(z){
        return x+y+z;
     }
   }
}

You can call like : sum(1)(2)(3)