Skip to content

Instantly share code, notes, and snippets.

@ericcornelissen
Last active January 28, 2019 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericcornelissen/54d54bcd324db64294103de837230174 to your computer and use it in GitHub Desktop.
Save ericcornelissen/54d54bcd324db64294103de837230174 to your computer and use it in GitHub Desktop.
Simple and small wrapper to allow for partial function invocation from left to right
/**
* Make a function partially invokable from left to right.
*
* @example
* let addThreeNumbers = partialLeft((a, b, c) => a + b + c);
* addThreeNumbers(1)(2)(3); // => 6
* addThreeNumbers(1, 2)(3); // => 6
* addThreeNumbers(1)(2, 3); // => 6
* addThreeNumbers(1, 2, 3); // => 6
*
* @param {Function} fn The function to make partially invokable.
* @return {Function} A partially invokable function.
* @license The-Unlicense
*/
function partialLeft(fn) {
// Check if the provided argument is a function
if (typeof fn !== 'function') throw Error('partialLeft should be provided with a function');
// Get the arity of the function
let arity = fn.length;
// Return the return value of resolver() which is a partially invokable function
return (function resolver() {
// Create *local* memory to allow for reuse of the partially invokable function
let memory = Array.from(arguments);
// Return the partally invoked function
return function() {
// Get the arguments from this call and combine them with the memory
let args = Array.from(arguments);
args = memory.concat(args);
// Call fn if enough arguments have been provided, otherwise return
// another partially invoked function
let next = args.length >= arity ? fn : resolver;
return next.apply(null, args);
};
}());
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment