public
Created

Function currying in JS

  • Download Gist
expamples.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/* 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
});
functional.js
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
/* 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)
 
});

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.