Last active
August 29, 2015 14:04
-
-
Save unscriptable/bb9f62add400fa45af61 to your computer and use it in GitHub Desktop.
One way to create a curry function. Currying: http://en.wikipedia.org/wiki/Currying
This file contains hidden or 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
module.exports = curry; | |
function curry (f) { | |
var arity = f.length; | |
var params = []; | |
var end = createEnd(f, arity); | |
return createCurried(params, arity, end); | |
} | |
function createEnd (f, arity) { | |
var src = 'return f('; | |
for (var i = 0; i < arity; i++) { | |
src += (i ? ', p[' : 'p[') + i + ']'; | |
} | |
src += ');'; | |
var endCall = new Function ('f', 'p', src); | |
return function end (p) { | |
return endCall(f, p); | |
}; | |
} | |
function createCurried (collected, arity, end) { | |
return function () { | |
var params = concat(collected, arguments); | |
return params.length < arity | |
? createCurried(params, arity, end) | |
: end(params); | |
} | |
} | |
function concat (a, b) { | |
var al = a.length; | |
var bl = b.length; | |
var c = new Array(al + bl); | |
var i; | |
for (i = 0; i < al; ++i) c[i] = a[i]; | |
for (i = 0; i < bl; ++i) c[i+al] = b[i]; | |
return c; | |
} |
Really cool. Here's a small variant that uses a dynamic compilation trick in order to give a name to the end
function--might help during debugging.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Seems like it'd be pretty fast because it avoids fn.apply(). However, since this this curry() ignores extra arguments, it can't be applied to functions with optional params that aren't reflected in the function's arity (length). :(
We would have to allow devs to supply an optional arity param to curry():