1 2 var comb = exports; 3 4 /** 5 * Determins if something is a function 6 * @param {Anything} obj the thing to test if it is a function 7 * 8 * @returns {Boolean} true if the obj is a function false otherwise 9 */ 10 comb.isFunction = function(obj) { 11 return typeof obj == "function"; 12 }; 13 14 /** 15 * Binds a method to a particular scope 16 * 17 * @param {Object} scope the scope to bind the callback to 18 * @param {String|Function} method the method to callback 19 * @param {Anything} [args] optional args to pass to the callback 20 * 21 * @returns {Function} the hitched function 22 */ 23 comb.hitch = function(scope, method, args) { 24 var args = Array.prototype.slice.call(arguments).slice(2); 25 if (typeof method == "string") { 26 method = scope[method]; 27 } 28 if (method) { 29 return function() { 30 var scopeArgs = args.concat(Array.prototype.slice.call(arguments)); 31 return method.apply(scope, scopeArgs); 32 }; 33 } else { 34 throw new Error(method + "Method not defined"); 35 } 36 }; 37 38 /** 39 * Allows the passing of additional arguments to a function when it is called 40 * especially useful for callbacks that you want to provide additional parameters to 41 * 42 * @param {String|Function} method the method to callback 43 * @param {Anything} [args] variable number of arguments to pass 44 * 45 * @returns {Function} partially hitched function 46 */ 47 comb.partial = function(method, args) { 48 var args = Array.prototype.slice.call(arguments).slice(1); 49 if (typeof method == "function") { 50 return function() { 51 var scopeArgs = args.concat(Array.prototype.slice.call(arguments)); 52 return method.apply(null, scopeArgs); 53 }; 54 } else { 55 throw new Error(method + "Method not defined"); 56 } 57 }; 58 59 var curry = function(f, execute) { 60 return function(arg) { 61 var args = Array.prototype.slice.call(arguments); 62 return execute ? f.apply(this, arguments) : function(arg) { 63 return f.apply(this, args.concat(Array.prototype.slice.call(arguments))); 64 }; 65 } 66 }; 67 68 /** 69 * Curries a function 70 * @example 71 * var curried = comb.curry(4, function(a,b,c,d){ 72 * return [a,b,c,d].join(","); 73 * } 74 * curried("a"); 75 * curried("b"); 76 * curried("c"); 77 * curried("d") => "a,b,c,d" 78 * 79 * //OR 80 * 81 * curried("a")("b")("c")("d") => "a,b,c,d" 82 * 83 * 84 * @param {Number} depth the number of args you expect 85 * @param {Function} cb the function to call once all args are gathered 86 * @param {Object} [scope] what scope to call the function in 87 * 88 * @returns {Function} the curried version of the function 89 * */ 90 comb.curry = function(depth, cb, scope) { 91 var f; 92 if (scope) { 93 f = comb.hitch(scope, cb); 94 } else { 95 f = cb; 96 } 97 if (depth) { 98 var len = depth - 1; 99 for (var i = len; i >= 0; i--) { 100 f = curry(f, i == len); 101 } 102 } 103 return f; 104 }; 105 106