Permalink
Fetching contributors…
Cannot retrieve contributors at this time
209 lines (150 sloc) 5.66 KB

Autonomy API

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 ]