return { uncurry: uncurry, flip: flip, plus: plus, minus: minus, times: times, divide: divide, gt: gt, ge: ge, eq: eq, neq: neq, teq: teq, tneq: tneq, lt: lt, le: le, and: and, or: or }; function uncurry(f) { return function() { var args = Array.prototype.slice.call(arguments); var result = f; while(args.length > 0 && typeof result == 'function') { result = result.apply(null, args.splice(0, result.length)); } return result; } } function flip(f) { return function(a, b) { return f(b)(a); } } function plus(a, b) { // keeping two arguments so that it can be curryied to Curry.plus by default return Array.prototype.reduce.call(arguments, function(acc, v) { return acc+v; }, 0); } function minus(a, b) { return a-b; } function times(a, b) { return Array.prototype.reduce.call(arguments, function(acc, v) { return acc*v; }, 1); } function divide(a, b) { return a/b; } function gt(a, b) { return a > b; } function ge(a, b) { return a >= b; } function eq(a, b) { return a == b; } function neq(a, b) { return a != b; } function teq(a, b) { return a === b; } function tneq(a, b) { return a !== b; } function lt(a, b) { return a < b; } function le(a, b) { return a <= b; } function and(a, b) { for(var i = 0; i < arguments.length; i++) { if(arguments[i] === false) { return false; } } return true; } function or(a, b) { for(var i = 0; i < arguments.length; i++) { if(arguments[i] === true) { return true; } } return false; }