Jyoti Prasad Pal Jyoti Prasad Pal - 4 months ago 10
Javascript Question

Currying in javascript for function with n parameters

If f :: (a, b) -> c, we can define curry(f) as below:

curry(f) :: ((a, b) -> c) -> a -> b -> c

const curry = f => a => b => f(a, b);
const sum = curry((num1, num2) => num1 + num2);
console.log(sum(2)(3)); //5


How do we implement generic curry function that takes a function with n parameters?

Answer

If I understand correctly, I think this is the way to go using ES6:

const curry = f => {
  const nargs = f.length;
  const vargs = [];
  const curried = (...args) => vargs.push(...args) >= nargs ? f(...vargs.slice(0, nargs)) : curried;
  
  return curried;
};

const arg2 = curry((a, b) => a + b);
const arg3 = curry((a, b, c) => a * (b + c));
const arg4 = curry((a, b, c, d) => Math.pow(a, b * (c + d)));

console.log(arg2(1)(2)); // 1 + 2
console.log(arg3(2)(3)(4)); // 2 * (3 + 4)
console.log(arg4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))

If you want to do this in ES5, here's a slightly more verbose method:

function curry(f) {
  var nargs = f.length;
  var vargs = [];
  
  return function curried () {
    var args = Array.prototype.slice.call(arguments);

    return vargs.push.apply(vargs, args) >= nargs ? f.apply(this, vargs.slice(0, nargs)) : curried;
  };
}

var arg2 = curry(function (a, b) {
  return a + b;
});
var arg3 = curry(function (a, b, c) {
  return a * (b + c);
});
var arg4 = curry(function (a, b, c, d) {
  return Math.pow(a, b * (c + d));
});

console.log(arg2(1)(2)); // 1 + 2
console.log(arg3(2)(3)(4)); // 2 * (3 + 4)
console.log(arg4(2)(1, 3)(4)); // 2 ^ (1 * (3 + 4))