Skip to content

Instantly share code, notes, and snippets.

@ryanseddon
Created November 6, 2013 02:46
Show Gist options
  • Save ryanseddon/7330082 to your computer and use it in GitHub Desktop.
Save ryanseddon/7330082 to your computer and use it in GitHub Desktop.
ES5 vs ES6 function currying
function curried(fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function() {
return fn.apply(this, args.concat(Array.prototype.slice.call(arguments, 0)));
}
}
function curried(fn, ...args) {
return (...nArgs) => fn.apply(this, [...args, ...nArgs])
}
@ryanseddon
Copy link
Author

Turns out this is partial application and actual function currying in ES6 would look like this:

function curried(fn, ...args) {
    var curry = (fnArgs) => {
        if(fnArgs.length >= fn.length) {
            return fn.apply(this, fnArgs);
        }

        return (...cArgs) => curry([...fnArgs, ...cArgs]);
    }
    return curry(args);
}

var add = curried(function(a,b){ return a + b;});
var increment = add(1);
// (...cArgs) => curry([...fnArgs, ...cArgs])
increment(4);
// 5
add(1, 2);
// 3

ES5:

function curry(fn) {
    var args = [].slice.call(arguments, 1);

    function curried(fnArgs) {
        if (fnArgs.length >= fn.length) {
            return func.apply(null, fnArgs);
        }

        return function () {
            return curried(fnArgs.concat([].slice.apply(arguments)));
        };
    }

    return curried(args);
}

@GreenGremlin
Copy link

I believe you need the spread operator on the curry argument, both on the definition and the initial call.

function curried(fn, ...args) {
    var curry = (...fnArgs) => {
        if(fnArgs.length >= fn.length) {
            return fn.apply(this, fnArgs);
        }

        return (...cArgs) => curry([...fnArgs, ...cArgs]);
    }
    return curry(...args);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment