0

For example let's take the function add. I want to be able to call:

add(1, 2)(3, 4)

and

add(1, 2)

using same implementation. I have tried writing the add function the following way:

var add = (a, b) => {
    return (c, d) => {
         return a + b + c + d;
    }
}

This will work fine for add(1, 2)(3, 4) but it will not work for add(1, 2). I am not sure how can I check if a function is passed arguments before returning it.

Ahmad Wehbe
  • 53
  • 1
  • 7
  • If you expect `add(1, 2)` to return a number, then you cannot call that number as if it was a function in `add(1, 2)(3, 4)`. – Bergi Sep 03 '22 at 22:56

2 Answers2

1

As there is no way for a function (when called) to know whether its return value will also be called like a function or not, the best you can do is to let the return value be callable and have a valueOf method, so that it can be used directly as a number in a larger expression that expects a number:

function add(...args) {
    let sum = 0;
    const f = function (...args) {
        for (const val of args) sum += val;
        return f;
    }
    f.valueOf = () => sum;
    return f(...args);
}

console.log(+add(1, 2)(3)(4, 5));

The "trick" here is that the + operator forces its operand to coerce to a number, and this will implicitly call the valueOf method of the function-object that add evaluates to. That + operator is just one of the many ways to get that valueOf method called. A few more examples:

console.log("result = " + add(1, 2)(3)(4, 5));
console.log(add(1, 2)(3)(4, 5) - 0);
console.log(add(1, 2)(3)(4, 5) * 1);
console.log(Number(add(1, 2)(3)(4, 5)));
trincot
  • 317,000
  • 35
  • 244
  • 286
0

You can send a third parameter to add function and return either function or value on the basis of that parameter. something like this -

var add = (a, b, returnType) => {
    if (returnType === 'function') {
        return (c, d) => {
            return a + b + c + d;
        }
    } else {
        return a + b;
    }
}