Last active
April 12, 2017 18:13
-
-
Save zspecza/b2abe98c263f108481fb0bb405622e18 to your computer and use it in GitHub Desktop.
curryN with placeholder support (not optimized)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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)