DEV Community

Discussion on: Currying in JS 🤠

Collapse
 
gypsydave5 profile image
David Wickes

CHALLENGE

Write a function that curries a function. It should take a function as an argument, and return the curried version.

NEXT LEVEL

Now write a function that uncurries a function.

Collapse
 
pnu profile image
Panu Ervamaa • Edited
const curry = (fn, ...args) =>
  args.length >= fn.length
    ? fn(...args)
    : (...x) => curry(fn, ...args, ...x);

const uncurry = (fn) => (...args) =>
  args.reduce((fn, arg) => fn(arg), fn);

const mul = (a, b) => a * b;
const curriedMul = curry(mul);
const mulBySeven = curriedMul(7);
const uncurriedMul = uncurry(curriedMul);

console.log(curriedMul(2)(3));    // 6
console.log(mulBySeven(11));      // 77
console.log(uncurriedMul(5, 7));  // 35
Collapse
 
aminnairi profile image
Amin
"use strict";

/**
 * Curry a function of any arity
 * 
 * @param {Function} callable
 * @param {unknown[]=} [] initialParameters
 * @return {Function}
 */
function curry(callable, ...initialParameters) {
    return function(...additionalParameters) {
        const parameters = [...initialParameters, ...additionalParameters];

        if (parameters.length >= callable.length) {
            return callable(...parameters);
        }

        return curry(callable, ...parameters);
    };
}

/**
 * Uncurry a function of any arity
 * 
 * @param {Function} curriedFunction
 * @return {Function}
 */
function uncurry(curriedFunction) {
    return function(...parameters) {
        return parameters.reduce(function(next, value) {
            return next(value);
        }, curriedFunction);
    }
}

const add = curry((x, y) => x + y);
const increment = add(1);

console.log(add);           // [Function]
console.log(increment);     // [Function]
console.log(add(1, 2));     // 3
console.log(increment(2));  // 3

const $add = uncurry(add);

console.log($add);          // [Function]
console.log($add(1, 2));    // 3