1

What would be the body of a the multiply function that if executed in both ways below would give the same result. So either calling multiply(2,4) or multiply(2)(4) would output 8?

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
KT-mongo
  • 2,044
  • 4
  • 18
  • 28
  • You can't call a function like that `multiply(2)(4)` – obscure May 29 '19 at 12:27
  • You can achieve both ways. However, you need some way to end the currying, just as you need a base case for recursion. That end condition can either be (1) the number of arguments, e.g. 2 in this case, (2) a final empty function call `add(1, 2)()` or `add(1)(2)()` or (3) some typecast at the end: `+add(1, 2)` or `+add(1)(2)` – Jonas Wilms May 29 '19 at 12:28
  • 1
    Yep - `multiply = (a, b) => b ? a * b : c => a * c` – Jack Bashford May 29 '19 at 12:29
  • nice and simple, as below answered by @Maheer Ali – KT-mongo May 29 '19 at 12:34

4 Answers4

1

You can check if second arg is passed or not.

function multiply(a,b){
  if(b === undefined){
    return function(b){
      return a * b;
    }
  }
  return a * b
}

console.log(multiply(2,4))
console.log(multiply(2)(4))
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73
0

Fairly simple - check if the second argument exists, and modify the return value accordingly:

const multiply = (a, b) => b ? a * b : c => a * c;
console.log(multiply(2, 3));
console.log(multiply(2)(4));

This can also be extended fairly simply to take three arguments:

const multiply = (a, b, c) => c ? a * b * c : (b ? (d => a * b * d) : (d, e) => a ? d * e : f => d * f);
console.log(multiply(2, 3, 4));
console.log(multiply(2, 5)(3));
console.log(multiply(2)(6, 3));
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

Whenever you have a curied function, you need some way to end the currying, just as you need a base case for recursion. That end condition can either be

(1) the number of arguments, e.g. 2 in this case:

  const curry = (fn, n) => {
     const c = (...args) => (...args2) => args.length + args.length >= n ? fn(...args, ...args2) : c(...args, ...args2);
     return c();
  };

  const add = curry((a, b) => a + b, 2);

(1b) For sure that can also be derived from the functions signature:

 const curry = (fn, ...keep) => (...args) => keep.length + args.length >= fn.length ? fn(...keep,  ...args) : curry(fn, ...keep, ...args);

 const add = curry((a, b) => a + b);

(2) a final empty function call e.g. add(1, 2)() or add(1)(2)()

   const curry = fn => (...args) => (...args2) => args2.length ? curry(fn)(...args, ...args2) : fn(...args, ...args2);

  const add = curry((a, b) => a + b);

(3) some typecast at the end, to trigger the result to be calculated, e.g. +add(1, 2) or +add(1)(2):

  const curry = (fn, ...keep) => {
    const c = (...args) => curry(fn, ...keep, ...args);
    c.valueOf = () => fn(...keep);
    return c;
  };

  const add = curry((a, b) => a + b);
Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

const multiply = (a,b) => !b ? (b) => a * b : a * b; 
console.log(multiply(2, 4))
console.log(multiply(2)(4))
Nicolae Maties
  • 2,476
  • 1
  • 16
  • 26