Skip to content

Instantly share code, notes, and snippets.

@alexdiliberto
Created May 4, 2014 15:57
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 alexdiliberto/5d2ef706331957e98041 to your computer and use it in GitHub Desktop.
Save alexdiliberto/5d2ef706331957e98041 to your computer and use it in GitHub Desktop.
Extends the previous curry.js to allow syntax with holes eg: fn("a", _, "c")("b")
function toArray(args) {
return [].slice.call(args);
}
function sub_curry(fn /*, variable number of args */) {
var args = [].slice.call(arguments, 1);
return function () {
return fn.apply(this, args.concat(toArray(arguments)));
};
}
function curry (fn, length, args, holes) {
length = length || fn.length;
args = args || [];
holes = holes || [];
return function() {
var _args = args.slice(0),
_holes = holes.slice(0),
argStart = _args.length,
holeStart = _holes.length,
arg, i;
for(i = 0; i < arguments.length; i++) {
arg = arguments[i];
if(arg === _ && holeStart) {
holeStart--;
_holes.push(_holes.shift()); // move hole from beginning to end
} else if (arg === _) {
_holes.push(argStart + i); // the position of the hole.
} else if (holeStart) {
holeStart--;
_args.splice(_holes.shift(), 0, arg); // insert arg at index of hole
} else {
_args.push(arg);
}
}
if(_args.length < length) {
return curry.call(this, fn, length, _args, _holes);
} else {
return fn.apply(this, _args);
}
}
}
var f = curry(function(a, b, c) { return [a, b, c]; });
var g = curry(function(a, b, c, d, e) { return [a, b, c, d, e]; });
// all of these are equivalent
f("a","b","c");
f("a")("b")("c");
f("a", "b", "c");
f("a", _, "c")("b");
f( _, "b")("a", "c");
//=> ["a", "b", "c"]
// all of these are equivalent
g(1, 2, 3, 4, 5);
g(_, 2, 3, 4, 5)(1);
g(1, _, 3)(_, 4)(2)(5);
//=> [1, 2, 3, 4, 5]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment