diff --git a/README.md b/README.md index 1b15e87..54bd09e 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ var d = c.map(function (x) { return x + 1; }); // some(42) ## Documentation -### contains(xs, x) +### array.contains(xs, x) `contains` takes an array and an element, and returns whether the element exists at least once in the array. @@ -36,7 +36,7 @@ var yep = contains([1,2,3], 2); // true var nope = contains([1,2,3], 4); // false ``` -### compose(f, g) +### fn.compose(f, g) [*demo*](http://jsfiddle.net/earldouglas/8q1znL7n/) @@ -67,7 +67,7 @@ var five = compose(inc, square)(2); // inc(square(2)) == (2 ^ 2) + 1 **g**: `function`, a unary function -### curry(f, args) +### fn.curry(f, args) `curry` takes an n-ary function `f` and an optional array of arguments, and returns a curried version of `f`, comprised of *n* nested unary functions @@ -100,7 +100,7 @@ var fortyTwo = curry(mathemagic)(2)(20)(1); **args**: `array`, [optional] arguments to apply to `f` -### memoize(f, cache) +### fn.memoize(f, cache) `memoize` takes a function and an optional cache implementation, and memoizes the function by backing it with the cache, if supplied, or a simple @@ -123,7 +123,7 @@ var fastResult = cheapFn(42); // cheap cache lookup the second time **cache**: `object`, [optional] a cache object with get(k) and put(k,v) functions -### lazy(f, cache) +### fn.lazy(f, cache) `lazy` takes a function and an optional cache implementation, and creates a function that, given input arguments, returns a lazy evaluator that will @@ -188,7 +188,7 @@ An option instance exposes the following fields: **value**: `any`, [optional] the value to wrap in an option -### collect(promises, callback) +### promise.collect(promises, callback) Given an array of promises and a callback, passes the result of each promise (in order) as an argument to the callback, and returns a single promise that @@ -217,7 +217,7 @@ p is congruent to `Promise.resolve(2 * (20 + 1))`, or `Promise.resolve(42)` **callback**: `function`, a function that takes as arguments the results of the promises -### valid(value) +### validation.valid(value) `valid` constructs a "validation" representing a valid value. @@ -234,7 +234,7 @@ A validation created by `valid` exposes the following fields: **value**: `any`, a valid value to wrap in a validation -### invalid(errors) +### validation.invalid(errors) `invalid` constructs a "validation" representing an invalid value, and containing an array of errors. diff --git a/doc.sh b/doc.sh deleted file mode 100755 index f462e6a..0000000 --- a/doc.sh +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash - -if [ -d doc ] -then - echo 'running: rm doc/*.md' - rm doc/*.md -else - echo 'running: mkdir doc' - mkdir doc -fi - -which jsdox > /dev/null -if [ $? -ne 0 ] -then - echo 'running: npm install jsdox' - npm install jsdox -fi - -echo 'running: jsdox lib --output doc' -jsdox lib --output doc - -pushd doc - -if [ -f _doc.md ] -then - echo 'running: rm _doc.md' - rm _doc.md -fi - -echo 'aggregating files' -for i in *.md -do - echo "running: cat $i >> _doc.md" - cat $i >> _doc.md - - echo "running: rm $i" - rm $i -done - -echo 'cleaning up' -sed -i '/^\* \* \*$/d' _doc.md -sed -i '/^# Global$/d' _doc.md - -mv _doc.md .. - -popd - -rmdir doc - -echo "documentation is now in `pwd`/_doc.md" diff --git a/lib/function.js b/lib/function.js index 87754ad..51fa76d 100644 --- a/lib/function.js +++ b/lib/function.js @@ -1,70 +1,11 @@ 'use strict'; -/** - * - * [*demo*](http://jsfiddle.net/earldouglas/8q1znL7n/) - * - * `compose` takes two unary functions `f` and `g`, and combines them into a - * single unary function `f ∘ g` that applies `g` to an input, passes the - * output to `f`, applies `f` to it, and returns the result. - * - * The application of `(f ∘ g)(x)` is equivalent to `f(g(x))`. - * - * *Example:* - * - * ```javascript - * function inc(x) { - * return x + 1; - * } - * - * function square(x) { - * return x * x; - * } - * - * var nine = compose(square, inc)(2); // square(inc(2)) == (2 + 1) ^ 2 - * var five = compose(inc, square)(2); // inc(square(2)) == (2 ^ 2) + 1 - * ``` - * - * @param f {function} a unary function - * @param g {function} a unary function - * - */ function compose(f, g) { return function (x) { return f(g(x)); }; } -/** - * `curry` takes an n-ary function `f` and an optional array of arguments, and - * returns a curried version of `f`, comprised of *n* nested unary functions - * where the arity of `f` is *n*. - * - * *Example:* - * - * ```javascript - * function add(x, y) { - * return x + y; - * }; - * - * var add2 = curry(add)(2); - * var five = add2(3); - * ``` - * - * *Example:* - * - * ```javascript - * function mathemagic(x, y, z) { - * return x * (y + z); - * }; - * - * var fortyTwo = curry(mathemagic)(2)(20)(1); - * ``` - * - * @param f {function} an n-ary function - * @param args {array} [optional] arguments to apply to `f` - * - */ function curry(f, args) { if (!args || !args.length) { args = []; @@ -87,26 +28,6 @@ function dumbCache() { }; } -/** - * `memoize` takes a function and an optional cache implementation, and - * memoizes the function by backing it with the cache, if supplied, or a simple - * object-based cache otherwise. - * - * *Example:* - * - * ```javascript - * function expensiveFn(n) { ... } - * - * var cheapFn = memoize(expensiveFn); - * - * var slowResult = cheapFn(42); // expensive computation the first time - * var fastResult = cheapFn(42); // cheap cache lookup the second time - * ``` - * - * @param f {function} an n-ary function - * @param cache {object} [optional] a cache object with get(k) and put(k,v) functions - * - */ function memoize(f, cache) { if (!cache) { cache = dumbCache(); @@ -124,27 +45,6 @@ function memoize(f, cache) { }; } -/** - * `lazy` takes a function and an optional cache implementation, and creates a - * function that, given input arguments, returns a lazy evaluator that will - * apply the function to the arguments only when needed, and only once if - * needed many times. - * - * *Example:* - * - * ```javascript - * function expensiveFn(n) { ... } - * - * var lazyVal = lazy(expensiveFn)(42); // lazily apply 42 -- no computation yet - * - * var slowResult = lazyVal.get(); // expensive computation the first time - * var fastResult = lazyVal.get(); // cheap cache lookup the second time - * ``` - * - * @param f {function} an n-ary function - * @param cache {object} [optional] a cache object with get(k) and put(k,v) functions - * - */ function lazy(f, cache) { var fMemo = memoize(f, cache); return function() { diff --git a/lib/list.js b/lib/list.js index ff9b409..7ddff12 100644 --- a/lib/list.js +++ b/lib/list.js @@ -20,26 +20,6 @@ function _cons(head, tail) { }; } -/** - * `list` constructs a linked list from a value, `head`, representing the first - * element in the list, and another list, `tail`, representing the rest of the - * constructed list. If `head` is null, `tail` is returned, and if `tail` is - * null, the empty list is returned. - * - * A list instance exposes the following fields: - * - * * `head` - the head of this list, if it is not empty - * * `tail` - the tail of this list, if it is not empty - * * `length` - returns the length of this list - * * `map(f)` - returns a new list created by applying `f` over this list - * * `flatMap(f)` - returns a new list created by applying `f` over this list and concatenating the results - * * `concat(l)` - returns the concatenation of this list with l - * * `toString()` - * - * @param head {any} the first element in the list - * @param tail {list} the rest of the list - * - */ function list(head, tail) { if (tail == null) { return list(head, _nil); @@ -50,4 +30,4 @@ function list(head, tail) { } } -exports.list = list; +module.exports = list; diff --git a/lib/option.js b/lib/option.js index 5722135..21aec35 100644 --- a/lib/option.js +++ b/lib/option.js @@ -1,21 +1,5 @@ 'use strict'; -/** - * `option` constructs a representation of an optional value, represented as - * either "some value" or "no value", depending on whether a non-null argument - * was supplied. - * - * An option instance exposes the following fields: - * - * * `empty` - * * `map(f)` - returns a new option by applying `f` over this option's value, and wrapping the result in an option - * * `flatMap(f)` - returns a new option by applying `f` over this option's value, and returning the result - * * `ap(a)` - assumes this option wraps a function, and returns a new option by mapping this option's function over the option `a` and returning the result - * * `toString()` - * - * @param value {any} [optional] the value to wrap in an option - * - */ function option(value) { if (value != null) { return { @@ -36,4 +20,4 @@ function option(value) { } } -exports.option = option; +module.exports = option; diff --git a/lib/promise.js b/lib/promise.js index 88d1363..89ffbd5 100644 --- a/lib/promise.js +++ b/lib/promise.js @@ -2,32 +2,6 @@ var curry = require('./function').curry; -/** - * Given an array of promises and a callback, passes the result of each promise - * (in order) as an argument to the callback, and returns a single promise that - * yields the result of the callback. - * - * Any of the promises can be 'lazy', implemented as a nullary function that - * returns a promise, and will be retrieved as late as possible. - * - * *Example:* - * - * ```javascript - * var p = collect([ - * Promise.resolve(2), - * Promise.resolve(20), - * Promise.resolve(1) - * ], function (x, y, z) { - * return x * (y + z); - * }); - * ``` - * - * p is congruent to `Promise.resolve(2 * (20 + 1))`, or `Promise.resolve(42)` - * - * @param promises {array} an array of promises - * @param callback {function} a function that takes as arguments the results of the promises - * - */ function collect(promises, callback) { var f = curry(callback); var p = promises.reduce(function (p1, p2) { diff --git a/lib/validation.js b/lib/validation.js index 654c89a..416acf3 100644 --- a/lib/validation.js +++ b/lib/validation.js @@ -1,20 +1,5 @@ 'use strict'; -/** - * `valid` constructs a "validation" representing a valid value. - * - * A validation created by `valid` exposes the following fields: - * - * * `valid` - returns true - * * `value` - returns the (valid) value - * * `map(f) - returns a new (valid) validation by mapping `f` over this validation's value and wrapping the in a (valid) validation - * * `flatMap(f) - returns a new validation result by mapping `f` over this validation's value and returning the result - * * `ap(a)` - assumes this validation wraps a function, and returns a new validation by mapping this validation's function over the validation `a` and returning the result - * * `toString()` - * - * @param value {any} a valid value to wrap in a validation - * - */ function valid(value) { return { valid : true, @@ -26,22 +11,6 @@ function valid(value) { }; } -/** - * `invalid` constructs a "validation" representing an invalid value, and - * containing an array of errors. - * - * A validation created by `invalid` exposes the following fields: - * - * * `valid` - returns false - * * `errors` - returns the array of errors - * * `map(f)` - returns a this validation - * * `flatMap(f)` - returns this validation - * * `ap(a)` - if `a` is valid, return this validation, otherwise returns a new (invalid) validation containing the concatenation of this validation's errors with `a`'s errors - * * `toString()` - * - * @param errors {array} an array of errors to wrap in a validation - * - */ function invalid(errors) { return { valid : false, diff --git a/teep.js b/teep.js index a6d5956..1ae3c63 100644 --- a/teep.js +++ b/teep.js @@ -18,13 +18,9 @@ var promise = require('./' + lib + '/promise'); var fn = require('./' + lib + '/function'); var array = require('./' + lib + '/array'); -exports.option = option.option; -exports.valid = validation.valid; -exports.invalid = validation.invalid; -exports.list = list.list; -exports.collect = promise.collect; -exports.curry = fn.curry; -exports.compose = fn.compose; -exports.memoize = fn.memoize; -exports.lazy = fn.lazy; -exports.array = array; +exports.option = option; +exports.validation = validation; +exports.list = list; +exports.promise = promise; +exports.fn = fn; +exports.array = array; diff --git a/test/function_test.js b/test/function_test.js index e21cd40..c5f3064 100644 --- a/test/function_test.js +++ b/test/function_test.js @@ -3,6 +3,7 @@ if (!global.Promise) { global.Promise = require('bluebird'); } var teep = require('../teep.js'); +var fn = teep.fn; function add(x, y) { return x + y; @@ -46,10 +47,10 @@ exports['fn'] = { return x * x; } - var nine = teep.compose(square, inc)(2); + var nine = fn.compose(square, inc)(2); test.equal(nine, 9); - var five = teep.compose(inc, square)(2); + var five = fn.compose(inc, square)(2); test.equal(five, 5); test.done(); @@ -57,11 +58,11 @@ exports['fn'] = { 'curry': function(test) { test.expect(2); - var add2 = teep.curry(add)(2); + var add2 = fn.curry(add)(2); var five = add2(3); test.equal(five, 5); - var fortyTwo = teep.curry(mathemagic)(2)(20)(1); + var fortyTwo = fn.curry(mathemagic)(2)(20)(1); test.equal(fortyTwo, 42); test.done(); @@ -69,7 +70,7 @@ exports['fn'] = { 'memoize': function(test) { test.expect(3); - var piMemo = teep.memoize(pi); + var piMemo = fn.memoize(pi); var N = 1000000; var est1 = time(function() { return piMemo(N); }); @@ -85,7 +86,7 @@ exports['fn'] = { test.expect(3); var N = 1000000; - var piLazy = teep.lazy(pi)(N); + var piLazy = fn.lazy(pi)(N); var est1 = time(function() { return piLazy.get(); }); var est2 = time(function() { return piLazy.get(); }); diff --git a/test/option_test.js b/test/option_test.js index 97baeb5..9aefbcd 100644 --- a/test/option_test.js +++ b/test/option_test.js @@ -1,49 +1,50 @@ 'use strict'; var teep = require('../teep.js'); +var option = teep.option; function inc(x) { return 1 + x; } exports['option'] = { 'option()': function(test) { test.expect(2); - test.equal(teep.option().empty, true, 'should be empty.'); - test.equal(teep.option().toString(), 'none()', 'should be none().'); + test.equal(option().empty, true, 'should be empty.'); + test.equal(option().toString(), 'none()', 'should be none().'); test.done(); }, 'option(42)': function(test) { test.expect(2); - test.equal(teep.option(42).empty, false, 'should not be empty.'); - test.equal(teep.option(42).toString(), 'some(42)', 'should be some(42).'); + test.equal(option(42).empty, false, 'should not be empty.'); + test.equal(option(42).toString(), 'some(42)', 'should be some(42).'); test.done(); }, 'option(false)': function(test) { test.expect(1); - test.equal(teep.option(false).toString(), 'some(false)', 'should not be empty.'); + test.equal(option(false).toString(), 'some(false)', 'should not be empty.'); test.done(); }, 'option(null)': function(test) { test.expect(1); - test.equal(teep.option(null).toString(), 'none()', 'should be empty.'); + test.equal(option(null).toString(), 'none()', 'should be empty.'); test.done(); }, 'map': function(test) { test.expect(2); - test.equal(teep.option().map(inc).toString(), 'none()', 'should be empty.'); - test.equal(teep.option(41).map(inc).toString(), 'some(42)', 'should be 42.'); + test.equal(option().map(inc).toString(), 'none()', 'should be empty.'); + test.equal(option(41).map(inc).toString(), 'some(42)', 'should be 42.'); test.done(); }, 'flatMap': function(test) { - function incLift(x) { return teep.option(1 + x); } + function incLift(x) { return option(1 + x); } test.expect(2); - test.equal(teep.option().flatMap(incLift).toString(), 'none()', 'should be empty.'); - test.equal(teep.option(41).flatMap(incLift).toString(), 'some(42)', 'should be 42.'); + test.equal(option().flatMap(incLift).toString(), 'none()', 'should be empty.'); + test.equal(option(41).flatMap(incLift).toString(), 'some(42)', 'should be 42.'); test.done(); }, 'ap': function(test) { test.expect(2); - test.equal(teep.option().ap(teep.option(41)).toString(), 'none()', 'should be empty.'); - test.equal(teep.option(inc).ap(teep.option(41)).toString(), 'some(42)', 'should be 42.'); + test.equal(option().ap(option(41)).toString(), 'none()', 'should be empty.'); + test.equal(option(inc).ap(option(41)).toString(), 'some(42)', 'should be 42.'); test.done(); }, }; diff --git a/test/promise_test.js b/test/promise_test.js index 3e33bdd..2c45b4d 100644 --- a/test/promise_test.js +++ b/test/promise_test.js @@ -3,6 +3,7 @@ if (!global.Promise) { global.Promise = require('bluebird'); } var teep = require('../teep.js'); +var promise = teep.promise; exports['promise'] = { 'promise.collect': function(test) { @@ -11,7 +12,7 @@ exports['promise'] = { var p2 = function () { return Promise.resolve(20); }; var p3 = Promise.resolve(1); var f = function (x, y, z) { return x * (y + z); }; - var p = teep.collect([p1, p2, p3], f); + var p = promise.collect([p1, p2, p3], f); p.then(function (x) { test.equal(x, 42); }).then(function () { diff --git a/test/validation_test.js b/test/validation_test.js index 11f3435..438820a 100644 --- a/test/validation_test.js +++ b/test/validation_test.js @@ -1,29 +1,30 @@ 'use strict'; var teep = require('../teep.js'); +var validation = teep.validation; function inc(x) { return 1 + x; } exports['validation'] = { 'map': function(test) { test.expect(2); - test.equal(teep.valid(41).map(inc).toString(), 'valid(42)', 'should be 42.'); - test.equal(teep.invalid(['wat']).map(inc).toString(), 'invalid(wat)', 'should be invalid(wat).'); + test.equal(validation.valid(41).map(inc).toString(), 'valid(42)', 'should be 42.'); + test.equal(validation.invalid(['wat']).map(inc).toString(), 'invalid(wat)', 'should be invalid(wat).'); test.done(); }, 'flatMap': function(test) { - function incLift(x) { return teep.valid(1 + x); } + function incLift(x) { return validation.valid(1 + x); } test.expect(2); - test.equal(teep.valid(41).flatMap(incLift).toString(), 'valid(42)', 'should be 42.'); - test.equal(teep.invalid(['wat']).flatMap(incLift).toString(), 'invalid(wat)', 'should be invalid(wat).'); + test.equal(validation.valid(41).flatMap(incLift).toString(), 'valid(42)', 'should be 42.'); + test.equal(validation.invalid(['wat']).flatMap(incLift).toString(), 'invalid(wat)', 'should be invalid(wat).'); test.done(); }, 'ap': function(test) { test.expect(4); - test.equal(teep.valid(inc).ap(teep.valid(41)).toString(), 'valid(42)', 'should be 42.'); - test.equal(teep.valid(inc).ap(teep.invalid(['wat'])).toString(), 'invalid(wat)', 'should be invalid(wat).'); - test.equal(teep.invalid(['wat']).ap(teep.valid(41)).toString(), 'invalid(wat)', 'should be invalid(wat).'); - test.equal(teep.invalid(['wat']).ap(teep.invalid(['nope'])).toString(), 'invalid(wat,nope)', 'should be invalid(wat).'); + test.equal(validation.valid(inc).ap(validation.valid(41)).toString(), 'valid(42)', 'should be 42.'); + test.equal(validation.valid(inc).ap(validation.invalid(['wat'])).toString(), 'invalid(wat)', 'should be invalid(wat).'); + test.equal(validation.invalid(['wat']).ap(validation.valid(41)).toString(), 'invalid(wat)', 'should be invalid(wat).'); + test.equal(validation.invalid(['wat']).ap(validation.invalid(['nope'])).toString(), 'invalid(wat,nope)', 'should be invalid(wat).'); test.done(); }, };