Skip to content

Instantly share code, notes, and snippets.

@fidel-karsto
Last active December 19, 2015 15:19
Show Gist options
  • Save fidel-karsto/5975326 to your computer and use it in GitHub Desktop.
Save fidel-karsto/5975326 to your computer and use it in GitHub Desktop.
curry / schönfinkel example
// http://blog.mgechev.com/2013/01/21/functional-programming-with-javascript/
/* By Stoyan Stafanov */
function schonfinkelize(fn) {
var slice = Array.prototype.slice,
stored_args = slice.call(arguments, 1);
return function () {
var new_args = slice.call(arguments),
args = stored_args.concat(new_args);
return fn.apply(null, args);
};
}
// http://benalman.com/news/2012/09/partial-application-in-javascript/#currying
function curry(fn, n) {
// If `n` argument was omitted, use the function .length property.
if (typeof n !== 'number') {
n = fn.length;
}
function getCurriedFn(prev) {
return function(arg) {
// Concat the just-specified argument with the array of
// previously-specified arguments.
var args = prev.concat(arg);
if (args.length < n) {
// Not all arguments have been satisfied yet, so return a curried
// version of the original function.
return getCurriedFn(args);
} else {
// Otherwise, invoke the original function with the arguments and
// return its value.
return fn.apply(this, args);
}
};
}
// Return a curried version of the original function.
return getCurriedFn([]);
}
function someThing(a,b,c) {
return (a + ", " + b + ", " + c);
}
function wait(count, callback){
while(count > 0) {
count--;
}
return callback;
}
console.time("procedure");
console.time("a");
var test = schonfinkelize(someThing, wait(10e4, "a"));
console.timeEnd("a");
console.time("b");
test = schonfinkelize(test, wait(10e6, "b"));
console.timeEnd("b");
console.time("c");
test("c");
console.timeEnd("c");
console.timeEnd("procedure");
console.log("-----");
console.time("procedure");
var testCurry = curry(someThing);
console.time("a");
var a = wait(10e4, "a");
console.timeEnd("a");
console.time("b");
var b = wait(10e6, "b");
console.timeEnd("b");
console.time("c");
var c = "c";
console.timeEnd("c");
console.time("currying");
console.log(testCurry(a)(b)(c));
console.timeEnd("currying");
console.timeEnd("procedure");
// ###### http://javascriptweblog.wordpress.com/2010/04/05/curry-cooking-up-tastier-functions/
Function.prototype.curry = function() {
if (arguments.length<1) {
return this; //nothing to curry with - return function
}
var __method = this,
_toArrayFn = Array.prototype.slice,
args = _toArrayFn.call(arguments);
return function() {
return __method.apply(this, args.concat(_toArrayFn.call(arguments)));
}
}
var converter = function(ratio, symbol, input) {
return [(input*ratio).toFixed(1),symbol].join(" ");
}
var kilosToPounds = converter.curry(2.2,"lbs");
var litersToUKPints = converter.curry(1.75, "imperial pints");
var litersToUSPints = converter.curry(1.98, "US pints");
var milesToKilometers = converter.curry(1.62, "km");
kilosToPounds(4); //8.8 lbs
litersToUKPints(2.4); //4.2 imperial pints
litersToUSPints(2.4); //4.8 US pints
milesToKilometers(34); //55.1 km
var BC = {};
BC.partial = function (fn) {
var slice = Array.prototype.slice,
args = slice.call(arguments, 1);
return (function() {
return fn.apply(this, args.concat(slice.call(arguments,0)));
});
}
BC.add = function (a, b) {
return a + b;
}
BC.increment = BC.partial(BC.add, 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment