Skip to content

Instantly share code, notes, and snippets.

@m3g4p0p
Last active November 11, 2016 20:34
Show Gist options
  • Save m3g4p0p/c57376ecb2d03029a23755633938cee7 to your computer and use it in GitHub Desktop.
Save m3g4p0p/c57376ecb2d03029a23755633938cee7 to your computer and use it in GitHub Desktop.
Simple curry function
// Placeholder
const _ = function _ () {}
// Curry a given function, optionally specifying
// a context on which it should finally get called
const curry = function curry (fn, thisArg) {
// Accumulate the call arguments for the curried function
return function accumulate () {
// The current arguments
const args = Array.from(arguments)
// The accumulated call arguments
const callArgs = Array
// `this` is the array of call arguments so far...
// just to avoid side effects ;-)
.from(this)
// Replace placeholders in the call arguments
// with the current arguments
.map(arg => arg === _ ? args.pop() || _ : arg)
// Append the remaining current arguments to the
// call arguments
.concat(args)
// If there are non-placeholder arguments missing
return fn.length - callArgs.filter(arg => arg !== _).length
// Wait for further arguments, binding the call
// arguments so far as the accumulation context
? accumulate.bind(callArgs)
// Otherwise apply the final call arguments to the
// function
: fn.apply(thisArg, callArgs)
// Start the currying with no arguments
}.bind([])
}
@m3g4p0p
Copy link
Author

m3g4p0p commented Nov 11, 2016

Sample usage

const calc = function (a, b, c) {
  return a + b * c
}

const curried = curry(calc)

// All logs `7`
console.log(curried(1, 2, 3))
console.log(curried(1)(2)(3))
console.log(curried(1)(2, 3))
console.log(curried(1, _, 3)(2))
console.log(curried(_, 2)(1)(3))
console.log(curried(1, _)(_, 3)(2))

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