const curryN = (arity, fn) => {

    // Take old arguments, and an array of new arguments
    const receiver = oldArgs => (...newArgs) => {

        const args = [...oldArgs, ...newArgs]; // Combine old and new arguments

        if (args.length >= arity) { // Have enough arguments have been received?
            return fn(...args); // Run fn with argument list
        }

        return receiver(args); // Recurse, and await further arguments

    };

    return receiver([]); // Start with an empty array of prior arguments

};

const curry = fn => curryN(fn.length, fn);