Write a Currying with multiple parameters

Viewed 69

In a recent interview, I was asked to write a function that adds numbers and accepts parameters like this:

console.log(sum())
console.log(sum()())
console.log(sum(1));
console.log(sum(1)());
console.log(sum(1)(2)()); 
console.log(sum(1, 2)()); 
console.log(sum(1)(2)(3)()); 
console.log(sum(1)(2, 3)()); 
console.log(sum(1)(2, 3)); 
console.log(sum(1)(2)(3)(4)()); 
console.log(sum(1)(2, 3, 4)());
console.log(sum(1, 2, 3, 4)()); 
console.log(sum(1, 2, 3, 4)); 

But I am not able to solve below answer, how to get default as 0 in below output?

console.log(sum())
console.log(sum()())
3 Answers

Well solution should be something like this:

const sum = (...args) => {
  const reducer = (acc, arg) => acc + arg;
  let total = args.reduce(reducer, 0)
  const add = (...args2) => {
    if (args2.length) {
      total = args2.reduce(reducer, total)
      return add
    }
    return total
  }

  add.toString = () => total;
  add.valueOf = () => total;

  return add
}



console.log(sum())
console.log(sum()())
console.log(sum(1));
console.log(sum(1)());
console.log(sum(1)(2)()); 
console.log(sum(1, 2)()); 
console.log(sum(1)(2)(3)()); 
console.log(sum(1)(2, 3)()); 
console.log(sum(1)(2, 3)); 
console.log(sum(1)(2)(3)(4)()); 
console.log(sum(1)(2, 3, 4)());
console.log(sum(1, 2, 3, 4)()); 
console.log(sum(1, 2, 3, 4)); 

It seems that I cannot quiet find a function that needs to be overriden in order to get nice output.

So in case of console.log(sum()) you will get ƒ add(). But if you write like this console.log("" + sum()) you will get 0 in console. console.log is not calling toString automatically :( probably some other method needs to be overriden additionally.

Using toString ad valueOf to get the result out. Using curried function with spread to get the passed in values as an array. Using reduce to do the addition.

function sum(...args){
    let v = 0;
    const f = (...args) => {
      v = args.reduce((x,n) => x + n, v);
      return f;
    };
    f.valueOf = f.toString = () => v;
    return f.apply(f, args);
}

console.log(sum())
console.log(sum()())
console.log(sum(1));
console.log(sum(1)());
console.log(sum(1)(2)()); 
console.log(sum(1, 2)()); 
console.log(sum(1)(2)(3)()); 
console.log(sum(1)(2, 3)()); 
console.log(sum(1)(2, 3)); 
console.log(sum(1)(2)(3)(4)()); 
console.log(sum(1)(2, 3, 4)());
console.log(sum(1, 2, 3, 4)()); 
console.log(sum(1, 2, 3, 4));

does this helps!

function curry(f) {
  return function(a) {
    return function(b) {
        /*return function(c) {
                return function(d) {
            return f(a, b, c, d);
        }       
      }*/      
      return f(a, b);
    };
  };
}

// usage
function sum(a, b /*, c, d*/) {
    if(a && b /*&& c && d*/) {
    return a + b; // + c + d;
  } else {
  return 0;
  }
  
}

const curriedSum = curry(sum);

document.write( curriedSum()() );
Related