1

I was asked this question in an interview.

for sum(2)(3) in currying style

sum(a) {
  return (b) {
    return a + b;
  }
}

for sum (2, 3)

sum(a, b) {
  return a + b;
}

Is there any common function which can work for both

Barmar
  • 596,455
  • 48
  • 393
  • 495
AkRoy
  • 323
  • 3
  • 10
  • You can make one, but it will be ugly, and imho bad code style. Just check, whether the second parameter is there, and if not, return the function, otherwise the result. – ASDFGerte Oct 01 '19 at 19:27
  • 3
    Check how many [`arguments`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments) you got and then return either the result or the inner function. – Bergi Oct 01 '19 at 19:27
  • Maximum 'unification': this can be solved with a single "+" in the code. – user2864740 Oct 01 '19 at 19:29
  • 1
    There's definitely a duplicate somewhere, I know I've answered this before... – Patrick Roberts Oct 01 '19 at 19:29
  • 1
    Possibly relevant: [Generalised Curry - Javascript](https://stackoverflow.com/questions/50616087/generalised-curry-javascript) – VLAZ Oct 01 '19 at 19:31

4 Answers4

0

There is a way, but it is quite hacky...

You can always check that a second argumet has been passed to your function and react accordingly

function sum(a, b){
    if(b === undefined){
        return (c) => {
            return c + a;
        }
    }

    return a + b;
}
zelitomas
  • 68
  • 8
0

You could return either the sum or a function based on the length of the arguments object.

function sum(a,b) {
  return arguments.length === 2   //were two arguments passed?
    ? a+b                         //yes: return their sum
    : (b) => a+b                  //no:  return a function
};

console.log(sum(3)(5));
console.log(sum(3,5));
Tyler Roper
  • 20,529
  • 6
  • 30
  • 51
0

Here's a function that can create a generalized curried function from any non-curried function. It is written without using any ECMAScript 6 syntax. This works regardless of the number of parameters expected by the original function, or the number of arguments provided to each partial application.

function sum (a, b) {
  return a + b;
}

function product (a, b, c) {
  return a * b * c;
}

function curry (fn) {
  return function partial () {
    return arguments.length >= fn.length
      ? fn.apply(this, arguments)
      : partial.bind.apply(partial, [this].concat(Array.prototype.slice.call(arguments)));
  };
}

var s = curry(sum);

console.log(s(1, 2));
console.log(s(1)(2));
console.log(s()()(1)()()(2));

var p = curry(product);

console.log(p(2, 3, 4));
console.log(p(2)(3)(4));
console.log(p()()(2)()()(3, 4));
Patrick Roberts
  • 40,065
  • 5
  • 74
  • 116
0

You can have a function that does both with infinite currying :

the idea here is to return a function as well as a computed value each time, so that if it is called again, the returned function will handle it, and if its not called, the computed value is printed.

function sum(...args) {
  function add(...args2) {
    return sum(...args, ...args2);
  }

  const t = [...args].reduce((acc, curr) => acc + curr, 0);
  add.value = t;

  return add;
}

const result1 = sum(2, 3).value;
const result2 = sum(2)(3).value;
const result3 = sum(2, 3)(4).value;
const result4 = sum(2, 3)(4, 5).value;
const result5 = sum(2, 3)(4, 5)(6).value;

console.log({ result1, result2, result3, result4, result5 });
Taki
  • 15,354
  • 3
  • 20
  • 39