Skip to content

Instantly share code, notes, and snippets.

@zspecza
Last active April 12, 2017 18:13
Show Gist options
  • Save zspecza/b2abe98c263f108481fb0bb405622e18 to your computer and use it in GitHub Desktop.
Save zspecza/b2abe98c263f108481fb0bb405622e18 to your computer and use it in GitHub Desktop.
curryN with placeholder support (not optimized)
// this file is just so I can reference the idea behind placeholders - if you want a maintained version, check out:
// - https://github.com/thisables/curry
// - http://ramdajs.com
const __ = Symbol
const ARITIES = {}
const setArity = (arity, fn) => {
if (!ARITIES[arity]) {
const params = Array(arity + 1).join(', _').substr(2)
ARITIES[arity] = new Function(
'fn',
`return function (${params}) { return fn.apply(this, arguments); }`
)
}
return ARITIES[arity](fn)
}
const ignoredPlaceholderLen = (params) =>
params.reduce((len, curr) => curr === __ ? len : len + 1, 0);
const hasPlaceholder = (args) => args.some(x => x === __)
const replacePlaceholders = (initialArgs, awaitedArgs) => {
const replacements = awaitedArgs.slice(0)
const newArgs = initialArgs.map((arg) => {
if (arg === __ && replacements[0]) {
arg = replacements.shift()
}
return arg
})
return [newArgs, replacements]
}
const ncurry = (arity, fn, ...initialArgs) => {
const len = hasPlaceholder(initialArgs) ? initialArgs.length : arity
const _curry = (...initialArgs) => {
const f = (...awaitedArgs) => {
[initialArgs, awaitedArgs] = replacePlaceholders(initialArgs, awaitedArgs)
const allArgs = initialArgs.concat(awaitedArgs)
if (ignoredPlaceholderLen(allArgs) >= len) {
return fn(...allArgs.slice(0, len))
}
return _curry(...allArgs)
}
return setArity(len - ignoredPlaceholderLen(initialArgs), f)
}
return _curry(...initialArgs)()
}
@zspecza
Copy link
Author

zspecza commented Dec 5, 2016

If g is a curried ternary function, then the following are equivalent:

  • g(1, 2, 3)
  • g(__, 2, 3)(1)
  • g(__, __, 3)(1)(2)
  • g(__, __, 3)(1, 2)
  • g(__, 2, __)(1, 3)
  • g(__, 2)(1)(3)
  • g(__, 2)(1, 3)
  • g(__, 2)(__, 3)(1)

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