Skip to content

Instantly share code, notes, and snippets.

@dannycallaghan
Created October 9, 2013 08:09
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 dannycallaghan/6897882 to your computer and use it in GitHub Desktop.
Save dannycallaghan/6897882 to your computer and use it in GitHub Desktop.
Currying / Partial Application From 'JavaScript Patterns' (O'Reilly) by Stoyan Stefanov.
/* Currying */
// Currying is making JavaScript functions understand and handle partial application
// A non-curried add functions
var add = function ( x, y ) {
return x + y;
};
// A curried add function
function add ( x, y ) {
if ( typeof y === "undefined" ) {
// partial application:
// if there's no second argument, the closure closes around the first argument,
// storing it's value, and returns a function ready to receive a second argument
return function ( y ) {
return x + y;
};
}
// full application:
// we have all the necessary arguments, so we just use a full application (non-curried) add function
return x + y;
}
add( 3, 4 ); // 7
add( 5 )( 4 ); // 9
var addSix = add( 1 );
console.log( typeof addSix ); // function
var result = addSix( 4 ) // 10
// A general purpose curry function
function curry ( fn ) {
var slice = Array.prototype.slice,
stored_args = slice.call( arguments, 1 );
return function () {
var new_args = slice.call( arguments ),
args = stored_args.concat( new_args );
return fn.apply( null, args );
};
}
// A non-curried add functions
var add = function ( x, y ) {
return x + y;
};
// curry a function to get a new function
var newadd = curry( add, 5 );
newadd( 4 ); // 9
// another option -- call the new function directly
curry( add, 6 )( 7 ); // 13
// Works with any number of params
// a normal function
function add( a, b, c, d, e ) {
return a + b + c + d + e;
}
curry( add, 1, 2, 3 )( 5, 5 ); // 16
// two-step currying
var addOne = curry( add, 1 );
addOne( 10, 10, 10, 10 ); // 41
var addSix = curry( addOne, 2, 3 );
addSix( 5, 5 ); // 16
// When to Use Currying
// When you find yourself calling the same function and passing mostly the same param- eters, then the function is
// probably a good candidate for currying. You can create a new function dynamically by partially applying a set of
// arguments to your function. The new function will keep the repeated parameters stored (so you don’t have to pass
// them every time) and will use them to pre-fill the full list of arguments that the original function expects.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment