5
function fn() {
    // implementation
}
fn(2,3,4); // 24
fn(2,3)(4); // 24
fn(2)(3)(4); // 24

I am not able to achieve the multiplication in the example shown above. How am I able to achieve it? Any kind of help is highly appreciated!

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
vennapusa
  • 209
  • 2
  • 11
  • 1
    It's called [`currying`](https://www.sitepoint.com/currying-in-functional-javascript/) and it is commonly used in Functional style programming. – Jason Cust Jun 04 '18 at 03:33

3 Answers3

10

You could have a function that returns itself with bound arguments if the total number of arguments provided so far is less than 3:

const multiply = (...args) => (
  args.length < 3
  ? multiply.bind(null, ...args)
  : args.reduce((a, b) => a * b)
);
console.log(multiply(2, 3, 4));
console.log(multiply(2, 3)(4));
console.log(multiply(2)(3)(4));
console.log(multiply(2)(3, 4));
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
3

    function curry(func,args,space) {
        var n  = func.length - args.length; //arguments still to come
        var sa = Array.prototype.slice.apply(args); // saved accumulator array
        function accumulator(moreArgs,sa,n) {
            var saPrev = sa.slice(0); // to reset
            var nPrev  = n; // to reset
            for(var i=0;i<moreArgs.length;i++,n--) {
                sa[sa.length] = moreArgs[i];
            }
            if ((n-moreArgs.length)<=0) {
                var res = func.apply(space,sa);
                // reset vars, so curried function can be applied to new params.
                sa = saPrev;
                n  = nPrev;
                return res;
            } else {
                return function (){
                    // arguments are params, so closure business is avoided.
                    return accumulator(arguments,sa.slice(0),n);
                }
            }
        }
        return accumulator([],sa,n);
    }
    // now you can define any type of function, add, Mul etc...
    function add (a,b,c){
          if (arguments.length < this.add.length) {
            return curry(this.add,arguments,this);
          }
          return a+b+c;
    }

    function mul (a,b,c){
        if (arguments.length < this.mul.length) {
          return curry(this.mul,arguments,this);
        }
        return a*b*c;
    }

    // Multiplication
    console.log("Multiplication Sample");
    console.log(mul(2,3,4))         // 24
    console.log(mul(2,3)(4))        // 24
    console.log(mul(2)(3)(4))       // 24
    console.log(mul()(1,2,4));      // 8
    console.log(mul(1)(2)(5));      // 10
    console.log(mul(1)()(2)()(6));  // 12

    // Addition
    console.log("Addition Sample");
    console.log(add(2,3,4))         // 9
    console.log(add(2,3)(4))        // 9
    console.log(add(2)(3)(4))       // 9
    console.log(add()(1,2,4));      // 7
    console.log(add(1)(2)(5));      // 8
    console.log(add(1)()(2)()(6));  // 9

Reference : http://www.crockford.com/javascript/www_svendtofte_com/code/curried_javascript/index.html

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Hiteshdua1
  • 2,126
  • 18
  • 29
  • [JavaScript has in most cases no tail call optimization](https://stackoverflow.com/questions/37224520/are-functions-in-javascript-tail-call-optimized). So be careful with functional programming in JavaScript. – ceving Jul 21 '20 at 13:22
1

This function can handle any size of input array or single value, just for output you have to pass empty param as shown in example

function multiply(...args){

         (args.length>0)? x=args.reduce((a, b) => a * b):x=1

 return  subfun=(...args)=>{
                (args.length>0)?  y=args.reduce((a, b) => a * b):y=args[0]
                 x= y? x*y:x
                 return y?subfun:x
                 }
          }


console.log(multiply(2, 3, 4)());
console.log(multiply(2, 3)(4)());
console.log(multiply(2)(3)(4)());
console.log(multiply(2)(3, 4)());

console.log(multiply(2)(3)() );
console.log(multiply(2)(3)(4)() );
console.log(multiply(2)(3)(4)(5)() );
console.log(multiply(2)(3)(4)(5)(6)());

console.log(multiply()(2)(3)(4)(5)(6)());
ceving
  • 21,900
  • 13
  • 104
  • 178
Jadli
  • 858
  • 1
  • 9
  • 17