Created
July 5, 2011 09:02
-
-
Save Gozala/1064515 to your computer and use it in GitHub Desktop.
Function currying in JS
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
/* vim:set ts=2 sw=2 sts=2 expandtab */ | |
/*jshint asi: true undef: true es5: true node: true devel: true | |
forin: true latedef: false supernew: true browser: true */ | |
/*global define: true port: true */ | |
!define(function(require, exports, module) { | |
var curry = require('./functional.js') | |
var sum = curry(function(a, b) { | |
return a + b | |
}) | |
console.log(sum(2, 2)) // 4 | |
console.log(sum(2)(4)) // 6 | |
var sum = curry(function() { | |
return Array.prototype.reduce.call(arguments, function(sum, number) { | |
return sum + number | |
}, 0) | |
}) | |
console.log(sum(2, 2)()) // 4 | |
console.log(sum(2, 4, 5)(-3)(1)()) // 9 | |
}); |
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
/* vim:set ts=2 sw=2 sts=2 expandtab */ | |
/*jshint asi: true undef: true es5: true node: true devel: true | |
forin: true latedef: false supernew: true browser: true */ | |
/*global define: true port: true */ | |
!define(function(require, exports, module) { | |
/** | |
* @param {Function} target | |
* Function to curry. | |
* @param {Number} [length=target.length||Infinity] | |
* Number of argument to curry. If not provided length of target function | |
* is used by default unless it's 0, in such case length will be infinity | |
* and function curry will stop once currier is executed without arguments. | |
*/ | |
exports.curry = function curry(target, length) { | |
length = length || target.length || Infinity | |
return function curried() { | |
var self = this, args = [] | |
return (function currier() { | |
// If no argument is being curried (`currier` is called with 0 | |
// arguments) and infinite number of arguments is expected we stop | |
// currying. Else if number of expected arguments is already collected | |
// we stop currying. One we stop currying we apply collected arguments | |
// to the target `funciton` and return result. If currying is not | |
// stopped we return `currier` to continue currying. | |
return ((args.length === args.push.apply(args, arguments) | |
&& Infinity === length) || args.length >= length) ? | |
target.apply(self, args) : currier | |
}).apply(self, arguments) | |
} | |
} | |
exports.compose = (function Compose(slice) { | |
return function compose() { | |
var funcs = slice.call(arguments) | |
return function composed() { | |
var args = slice.call(arguments) | |
var i = funcs.length | |
while (0 <= --i) args = [ funcs[i].apply(this, args) ] | |
return args[0] | |
} | |
} | |
})(Array.prototype.slice) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment