1

I'm trying to implement currying function:

function sum(a, b, c) {
console.log('SUM'+JSON.stringify(arguments))
  return a + b + c;
}

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func.apply(this,n.concat(args2));


  };

}

curry(sum,1,2)(3) //SUM{"0":1,"1":2,"2":3}, O/P:6

Above gives correct output, but i am not getting the necessity to use apply.

So, if i change my function to below:

var curry= function (func,...n) {
      return function(...args2) {
         //console.log('arg2s'+args2)
        return func(n.concat(args2));


  };

}
curry(sum,1,2)(3) //SUM{"0":[1,2,3]}  O/P:"1,2,3undefinedundefined"

I basically have two questions here:

  1. Why is the implementation of curry not working when calling func directly?Why is the output such weird ?

2.How do i change my function in a way that i can call it as below and should return sum: curry(1)(2)(3)/curry(1,2)(3)/curry(1,2,3) etc instead of the way i'm calling currently. I could find some solutions on the web, but couldn't understand .

ex:

function curry(func) {

  return function curriedFunc(...args) {
    if (args.length >= func.length) {
      return func.apply(this, args);
    } else {
      return function(...args1) {
        return curriedFunc.apply(this, args.concat(args1));
      }
    }
  };

}

Any help would be highly appreciated !!

1 Answer 1

1

Your func accepts three arguments: a, b, and c. When you do:

return func(n.concat(args2));

you're passing it one argument, an array. It's equivalent to:

const arr = n.concat(args2);
return func(arr);

Sounds like you'd want to spread the arguments into the call of func instead:

return func(...n, ...args2)

With spread syntax, each item from the iterable is put into a parameter. Eg, if the n array has one item, it gets set as the first argument passed to func, and if args2 has 2 items, the first gets set as the second argument passed, and the second gets set as the third argument passed.

function sum(a, b, c) {
  console.log('SUM' + JSON.stringify(arguments))
  return a + b + c;
}

var curry = function(func, ...n) {
  return function(...args2) {
    return func(...n, ...args2);
  };

}
curry(sum, 1, 2)(3);

How do i change my function in a way that i can call it as below and should return sum: curry(1)(2)(3)/curry(1,2)(3)/curry(1,2,3) etc

Keep track of the total number of arguments passed in a closure created the first time the function is called. In the returned function, push all arguments to the array, and if the array's length is 3, return the sum, otherwise return the function again:

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

var curry = function(func, ...argsSoFar) {
  const neededArgs = func.length;
  const returnedFn = (...args) => {
    argsSoFar.push(...args);
    if (argsSoFar.length === neededArgs) {
      return func(...argsSoFar);
    } else {
      return returnedFn;
    }
  };
  return returnedFn;
}
console.log(
  curry(sum, 1, 2)(3),
  curry(sum)(1, 2)(3),
  curry(sum)(1)(2, 3),
  curry(sum)(1)(2)(3),
);

Sign up to request clarification or add additional context in comments.

4 Comments

How was return func.apply(this,n.concat(args2)); taking care of it? Only difference is use of apply here.. how was apply handling the arguments ?(Problem 1)
apply takes an array (2nd parameter) and calls the function with each item of the array as an argument. If this isn't an issue, fn.apply(null, args) is exactly equivalent to fn(...args). Your original code was doing the equivalent of fn(args).
Thank u soooooo much... i missed this(apply takes array and passes argument one after the other from array).Also, the explanation for use of spread operator makes sense.Thanks
I thought of checking Solution for Problem 2 and then marking resolved.. sorry.. accepted it :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.