Autonomy API
January 28, 2016 ยท View on GitHub
Autonomy exports basic functional helpers, looping constructs, functional sequencers which aims to complement existing ES5 methods with a slight functional style.
This module is often bundled with interlude, where extra functions exist on the imported object. This API will only mention functions existing in the interlude-less case.
Functional Helpers
id(x) :: x
The identity function f(x) = x.
var x = "going through the identity";
id(x) === x; // true
noop([..]) :: undefined
No operation. Does nothing.
var log = console ? console.log : noop;
log("log this if possible");
not(fn) :: (x) -> Boolean
Returns a function which negates fn results.
Sometimes useful for composing certain functions.
[8,3,4,5,6].filter(not((x) => x > 5)); // [3, 4, 5]
var partition = (p, xs) => [xs.filter(p), xs.filter(not(p))];
partition((x) => x > 5, [8,3,4,5,6]); // [ [ 8, 6 ], [ 3, 4, 5 ] ]
all(fn) :: (xs) -> Boolean
An accessor for Array.prototype.every, but with the function curried.
[[3,4], [1,3], [2,3]].filter(all(elem([1, 3, 4]))); // [ [ 3, 4 ], [ 1, 3 ] ]
any(fn) :: (xs) -> Boolean
An accessor for Array.prototype.some, but with the function curried.
any((x) => x > 2)([1,2,3]); // true
[[3,4,5], [4,5,6]].filter(any(elem([6, 7]))); // [ [ 4, 5, 6 ] ]
none(fn) :: (xs) -> Boolean
An accessor for the negated Array.prototype.some, but with the function curried.
elem(xs) :: (x) -> Boolean
notElem(xs) :: (x) -> Boolean
The membership tests are accessors for Array.prototype.indexOf, but with the array curried.
[1,2,3,4,3].filter(elem([1,3])); // [ 1, 3, 3 ]
[1,2,3,4,3].filter(notElem([1,3])); // [ 2, 4 ]
Math
Helpers for Integers.
gcd(a, b) :: Int
Returns the greatest common divisor (aka highest common factor) of two Integers.
gcd(3, 5); // 1
gcd(10, 15); // 5
lcm(a, b) :: Int
Returns the least common multiple of the Integers a and b.
lcm(3, 5); // 15
lcm(10, 15); // 30
even(n), odd(n) :: Boolean
Returns whether or not the number is even or odd, respectively.
even(5); // false
odd(5); // true
[1,2,3,4,5,6].filter(even); // [ 2, 4, 6 ]
Property Accessors
These are shortcut functions for extracting a property of an element.
pluck(prop, xs) :: ys
Shorthand for of a common use-case for Array.prototype.map; extracting simple property values.
pluck('length', [ [1,3,2], [2], [1,2] ]); // [ 3, 1, 2 ]
first(xs) :: x
Finds the first element of xs.
last(xs) :: x
Finds the last element of xs.
firstBy(fn, xs) :: x
Finds the first element x in xs for which fn(x) is true.
lastBy(fn, xs) :: x
Finds the last element x in xs for which fn(x) is true.
var ary = [{a:2}, {a:2, b:1}, {a:3}];
var aEq2 = (x) => x.a === 2;
firstBy(aEq2, ary); // {a:2}
lastBy(aEq2, ary); // {a:2, b:1}
last(ary); // {a:3}
Looping Constructs
These tools allow loop like code to be written in a more declarative style.
range(length) :: [1 , 2 , .. , length]
Returns a 1-indexed inclusive range from of size length.
range(5); // [ 1, 2, 3, 4, 5 ]
interval(a, b) :: [a, a + 1, .. , b]
Returns a closed interger interval from a to b
interval(2, 5); // [ 2, 3, 4, 5 ]
replicate(n, fn) :: [Result]
Returns an n length Array with the return value of a passed in fn.
replicate(5, () => 2); // [ 2, 2, 2, 2, 2 ]
replicate(3, (v, k) => [k]); // [ [0], [1], [2] ]
// call cluster.fork 5 times in map without passing accidental arguments
replicate(5).map(cluster.fork); // maps undefined -> cluster.fork
iterate(times, init, fn) :: [Result]
Returns a size times array of repeated applications of fn to init:
iterate(times, x, f) equals [x, f(x), f(f(x)), ...]
iterate(5, 2, op.times(2)); // [ 2, 4, 8, 16, 32 ]
// Fibonacci numbers
var fibPairs = iterate(8, [0,1], (x) => [x[1], x[0] + x[1]]);
pluck(0, fibPairs);
// [ 0, 1, 1, 2, 3, 5, 8, 13 ]
zipN(xs, ys [, zs [, ws]]) :: [Tuple]
zip takes between 2 and 4 arrays (depending on function chosen) and returns a single array of n length arrays by joining the input arrays on index. If any input array is short, excess elements of the longer arrays are discarded.
zip2([1,2,3], [2,2,2]); // [ [1,2], [2,2], [3,2] ]
zip3(range(5), [1,2], [3,2,5]); // [ [1,1,3], [2,2,2] ]
Note that zip may be used as an alias for zip2.
zipWithN(fn, xs, ys [, zs [, ws]]) :: [Result]
Same as zip, but applies each result array to fn, and collects these results.
zipWith generalises zip by zipping with the function given as the first argument, instead of a collecting the elements as tuples. For example, zipWith((x, y) => x+y, xs, ys) is applied to two arrays to produce the array of corresponding sums.
zipWith2((x, y) => x + y, [1,1,1], range(5)); // [ 2, 3, 4 ]
zipWith3((x, y, z) => x*y*z, [2,2,2], [1,0,1], [1,2,3]); // [ 2, 0, 6 ]
Note that zipWith may be used as an alias for zipWith2.
Curried Prototype Method Accessors
map(fn) :: (xs) -> results
An accessor for Array.prototype.map, but with the function curried.
[[1,2], [3,4]].map(map((x, y) => x+y)); // [ [ 2, 3 ], [ 4, 5 ] ]
filter(fn) :: (xs) -> results
An accessor for Array.prototype.filter, but with the function curried.
reduce(fn [, start]) :: (xs) -> results
An accessor for Array.prototype.reduce, but with the function curried.
var product = reduce((x, y) => x * y, 1);
var factorial = (n) => product(range(n));
factorial(4); // 24
var flatten = reduce((xs, ys) => xs.concat(ys), []);
flatten([[1,2,3], [[1]], [2,3]]); // [ 1, 2, 3, [ 1 ], 2, 3 ]