foreword
Version:
A JavaScript library for functional data transformation
1,884 lines (1,304 loc) • 33.8 kB
Markdown
add](
- [always](
- [and](
- [ap](
- [apply](
- [ascend](
- [ascendBy](
- [between](
- [both](
- [branch](
- [clamp](
- [complement](
- [compose](
- [curry](
- [dec](
- [descend](
- [descendBy](
- [divide](
- [either](
- [equal](
- [equalBy](
- [flip](
- [gt](
- [gte](
- [id](
- [inc](
- [isEven](
- [isOdd](
- [lt](
- [lte](
- [match](
- [max](
- [min](
- [mod](
- [multiply](
- [negate](
- [not](
- [on](
- [or](
- [pipe](
- [pow](
- [rem](
- [subtract](
- [unless](
- [when](
- [Array](
- [append](
- [concat](
- [concatMap](
- [countBy](
- [drop](
- [dropWhile](
- [every](
- [filter](
- [find](
- [get](
- [gets](
- [groupBy](
- [head](
- [includes](
- [indexOf](
- [init](
- [isEmpty](
- [last](
- [length](
- [map](
- [max](
- [maxBy](
- [min](
- [minBy](
- [partition](
- [prepend](
- [range](
- [reduce](
- [reject](
- [reverse](
- [scan](
- [slice](
- [some](
- [sort](
- [sortBy](
- [sortWith](
- [span](
- [tail](
- [take](
- [takeWhile](
- [unique](
- [uniqueBy](
- [zip](
- [Maybe](
- [encase](
- [isNothing](
- [map](
- [toArray](
- [withDefault](
- [Object](
- [concat](
- [every](
- [filter](
- [find](
- [get](
- [gets](
- [includes](
- [isEmpty](
- [length](
- [map](
- [reject](
- [some](
- [update](
- [String](
- [append](
- [concat](
- [drop](
- [dropWhile](
- [includes](
- [indexOf](
- [isEmpty](
- [join](
- [length](
- [repeat](
- [replace](
- [reverse](
- [search](
- [slice](
- [span](
- [split](
- [take](
- [takeWhile](
- [toLower](
- [toUpper](
- [trim](
---
<div id="basics" class="section-name"></div>
```javascript
const F = require('foreword')
// or
const { add, always, ... } = require('foreword')
```
<div id="number-add" class="section-name"></div>
`Number -> Number -> Number`
Adds two numbers.
```javascript
add(2, 2)
//=> 4
```
<div id="function-always" class="section-name"></div>
`a -> b -> a`
Returns its first argument.
```javascript
always('a', 'b')
//=> 'a'
```
<div id="function-and" class="section-name"></div>
`Boolean -> Boolean -> Boolean`
Returns `true` if both values are `true`.
```javascript
and(true, false)
//=> false
```
<div id="function-ap" class="section-name"></div>
`Array (a -> b) -> Array a -> Array b`
Applies a list of functions over a list of values.
```javascript
ap([mul(2), add(3)], [1, 2, 3])
//=> [ 2, 4, 6, 4, 5, 6 ]
```
<div id="function-apply" class="section-name"></div>
`(a -> b) -> a -> b`
Applies function to value.
```javascript
apply(add(1), 1)
//=> 2
```
<div id="function-ascend" class="section-name"></div>
`a -> a -> Number`
Takes two comparables and returns a number for sorting in ascending order.
```javascript
A.sort(ascend, [3, 1, 2])
//=> [ 1, 2, 3 ]
```
<div id="function-ascendBy" class="section-name"></div>
`(a -> b) -> a -> a -> Number`
Takes a function and applies it over two comparable values for sorting in ascending order.
```javascript
A.sort(ascendBy(O.get('name')), [{ name: 'bob' }, { name: 'alice' }])
//=> [ { name: 'alice' }, { name: 'bob' } ]
```
<div id="number-between" class="section-name"></div>
`Number -> Number -> Number -> Boolean`
Determines if a number is between two predicate numbers.
```javascript
const test = between(0, 10)
test(5)
//=> true
test(20)
//=> false
```
<div id="function-both" class="section-name"></div>
`(a -> Boolean) -> (a -> Boolean) -> a -> Boolean`
Applies a value over two predicate functions, returns the result of an `and` comparison. Short-circuits if the first predicate returns false.
```javascript
const test = both(gt(10), lt(20))
test(15)
//=> true
test(30)
//=> false
```
<div id="function-branch" class="section-name"></div>
`(a -> Boolean) -> (a -> b) -> (a -> b) -> b`
If the predicate is matched, apply the first function, otherwise apply the second.
```javascript
const test = branch(gt(10), dec, inc)
test(11)
//=> 10
test(9)
//=> 10
```
<div id="number-clamp" class="section-name"></div>
`Number -> Number -> Number -> Number`
Retricts a number to be within a range.
```javascript
const test = clamp(1, 10)
test(0)
//=> 1
test(20)
//=> 10
test(5)
//=> 5
```
<div id="function-complement" class="section-name"></div>
`(a -> Boolean) -> a -> Boolean`
Returns the opposite boolean value that the predicate returned.
```javascript
complement(equal(1), 1)
//=> false
```
<div id="function-compose" class="section-name"></div>
`(b -> c) -> (a -> b) -> a -> c`
Applies value through two functions, from right to left.
```javascript
compose(Math.sqrt, add(1), 99)
//=> 10
```
<div id="function-curry" class="section-name"></div>
`Number -> ((a, b) -> c) -> a -> b -> c`
Wraps a function and allows you to supply your arguments one at a time.
```javascript
const add = curry(2, (a, b) => a + b)
const add1 = add(1)
add1(1)
//=> 2
```
<div id="number-dec" class="section-name"></div>
`Number -> Number`
Decrements a number.
```javascript
dec(10)
//=> 9
```
<div id="number-divide" class="section-name"></div>
`Number -> Number -> Number`
Divides two numbers.
```javascript
divide(2, 10)
//=> 5
```
<div id="function-descend" class="section-name"></div>
`a -> a -> Number`
Takes two comparables and returns a number for sorting in descending order.
```javascript
A.sort(descend, [3, 1, 2])
//=> [ 3, 2, 1 ]
```
<div id="function-descendBy" class="section-name"></div>
`(a -> b) -> a -> a -> Number`
Takes a function and applies it over two comparable values for sorting in descending order.
```javascript
A.sort(descendBy(O.get('name')), [{ name: 'bob' }, { name: 'alice' }])
//=> [ { name: 'bob' }, { name: 'alice' } ]
```
<div id="function-either" class="section-name"></div>
`(a -> Boolean) -> (a -> Boolean) -> a -> Boolean`
Applies a value over two predicate functions, returns the result of an `or` comparison. Short-circuits if the first predicate returns true.
```javascript
const test = either(gt(10), isEven)
test(15)
//=> true
test(5)
//=> false
test(4)
//=> true
```
<div id="function-equal" class="section-name"></div>
`a -> a -> Boolean`
Returns the result of comparing two values.
```javascript
equal('abc', 'abc')
//=> true
equal('abc', 'xyz')
//=> false
```
<div id="function-equalBy" class="section-name"></div>
`a -> a -> Boolean`
Returns the result of comparing two values, after applying a function over the values
```javascript
equalBy(Math.abs, 5, -5)
//=> true
```
<div id="function-flip" class="section-name"></div>
`(a -> b -> c) -> b -> a -> c`
Reverses the order of the first two arguments of the provided function.
```javascript
const gt_ = flip(gt)
gt_(1, 2)
//=> false
```
<div id="function-gt" class="section-name"></div>
`a -> a -> Boolean`
Determines if a value is greater.
```javascript
gt(1, 2)
//=> true
gt('a', 'b')
//=> true
```
<div id="function-gte" class="section-name"></div>
`a -> a -> Boolean`
Determines if a value is greater than or equal.
```javascript
gte(1, 1)
//=> true
gte(1, 2)
//=> true
```
<div id="function-id" class="section-name"></div>
`a -> a`
Returns itself.
```javascript
id('a')
//=> 'a'
A.filter(id, [0, 1, null, 'test'])
//=> [ 1, 'test' ]
```
<div id="number-inc" class="section-name"></div>
`Number -> Number`
Increments a number.
```javascript
inc(10)
//=> 11
```
<div id="number-isEven" class="section-name"></div>
`Number -> Boolean`
Determines if a number is even.
```javascript
isEven(10)
//=> true
```
<div id="number-isOdd" class="section-name"></div>
`Number -> Boolean`
Determines if a number is odd.
```javascript
isOdd(9)
//=> true
```
<div id="function-lt" class="section-name"></div>
`a -> a -> Boolean`
Determines if a value is lesser.
```javascript
lt(2, 1)
//=> true
```
<div id="function-lte" class="section-name"></div>
`a -> a -> Boolean`
Determines if a value is less than or equal.
```javascript
lte(1, 1)
//=> true
lte(2, 1)
//=> true
```
<div id="function-match" class="section-name"></div>
`Array (a -> Maybe b) -> a -> Maybe b`
Contains a list of functions that return a value or `undefined`, working well with [when](
```javascript
const fn = match([
when(lt(10), inc),
when(gt(10), dec),
when(always(true), id)
])
fn(1)
//=> 2
fn(15)
//=> 14
fn(10)
//=> 10
```
<div id="number-max" class="section-name"></div>
`Number -> Number -> Number`
Returns the larger number.
```javascript
max(4, 9)
//=> 9
```
<div id="number-min" class="section-name"></div>
`Number -> Number -> Number`
Returns the smaller number.
```javascript
min(4, 9)
//=> 4
```
<div id="number-mod" class="section-name"></div>
`Number -> Number -> Number`
Behaves like the mathematical modulo operator.
```javascript
mod(-20, 3)
//=> 1
```
<div id="number-multiply" class="section-name"></div>
`Number -> Number -> Number`
Multiplies two numbers.
```javascript
multiply(2, 5)
//=> 10
```
<div id="number-negate" class="section-name"></div>
`Number -> Number`
Negated number.
```javascript
negate(10)
//=> -10
```
<div id="function-not" class="section-name"></div>
`Boolean -> Boolean`
Returns the opposite boolean value.
```javascript
not(true)
//=> false
not(A.some(equal(1), [1, 2, 3]))
//=> false
```
<div id="function-on" class="section-name"></div>
`(b -> b -> c) -> (a -> b) -> a -> a -> c`
Applies a binary function over a unary function twice.
```javascript
const sameLength = on(equal, S.length)
sameLength('hey', 'now')
//=> true
```
<div id="function-or" class="section-name"></div>
`Boolean -> Boolean -> Boolean`
Returns `true` if one or both values are `true`.
```javascript
or(true, false)
//=> true
```
<div id="function-pipe" class="section-name"></div>
`Array (a -> b) -> a -> b`
Applies a sequence of transformations over a value.
```javascript
pipe([add(1), Math.sqrt], 99)
//=> 10
```
<div id="number-pow" class="section-name"></div>
`Number -> Number -> Number`
Returns the power.
```javascript
pow(2, -2)
//=> 4
```
<div id="number-rem" class="section-name"></div>
`Number -> Number -> Number`
Returns the remainder.
```javascript
rem(3, -20)
//=> -2
```
<div id="number-subtract" class="section-name"></div>
`Number -> Number -> Number`
Subtracts two numbers.
```javascript
subtract(2, 10)
//=> 8
```
<div id="function-unless" class="section-name"></div>
`(a -> Boolean) -> (a -> b) -> a -> Maybe b`
If the predicate is not matched, run a transformer function, otherwise return `undefined`.
```javascript
unless(lt(10), inc, 15)
//=> 16
unless(lt(10), inc, 5)
//=> 5
```
<div id="function-when" class="section-name"></div>
`(a -> Boolean) -> (a -> b) -> a -> Maybe b`
If the predicate is matched, run a transformer function, otherwise return `undefined`.
```javascript
when(lt(10), inc, 5)
//=> 6
```
---
<div id="array" class="section-name"></div>
```javascript
const A = require('foreword/array')
```
<div id="array-append" class="section-name"></div>
`a -> Array a -> Array a`
Adds a value to the end of an array.
```javascript
A.append(4, [1, 2, 3])
//=> [ 1, 2, 3, 4 ]
A.append([4], [1, 2, 3])
//=> [ 1, 2, 3, [ 4 ] ]
```
<div id="array-concat" class="section-name"></div>
`Array a -> Array a`
Concatenate an array of arrays into a single array, removing one level of nesting.
```javascript
A.concat([[1, 2], [3], [4, 5]])
//=> [ 1, 2, 3, 4, 5 ]
```
<div id="array-concatMap" class="section-name"></div>
`(a -> Array b) -> Array a -> Array b`
Concatenates the result of a map function.
```javascript
A.concatMap(x => [x, x], [1, 2, 3])
//=> [ 1, 1, 2, 2, 3, 3 ]
A.concatMap(x => A.range(1, inc(x)), [1, 2, 3])
//=> [ 1, 1, 2, 1, 2, 3 ]
```
<div id="array-countBy" class="section-name"></div>
`(a -> b) -> Array a -> Object b Number`
Returns an object with keys as the result of applying a function to elements, and the value is the amount of every matched element.
```javascript
A.countBy(Math.floor, [4.2, 6.1, 6.4])
//=> { 4: 1, 6: 2 }
A.countBy(S.length, ['one', 'two', 'three'])
//=> { 3: 2, 5: 1 }
```
<div id="array-drop" class="section-name"></div>
`Number -> Array a -> Array a`
Drops the first n elements in an array.
```javascript
A.drop(2, [1, 2, 3, 4, 5])
//=> [ 3, 4, 5 ]
```
<div id="array-dropWhile" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array a`
Drops the first items of an array which match the predicate.
```javascript
A.dropWhile(isEven, [2, 4, 5, 6])
//=> [ 5, 6 ]
```
<div id="array-every" class="section-name"></div>
`(a -> Boolean) -> Array a -> Boolean`
Determines if every element satisfies the predicate.
```javascript
A.every(equal(1), [1, 1, 1])
//=> true
A.every(equal('a'), ['a', 'b', 'c'])
//=> false
```
<div id="array-filter" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array a`
Returns an array of every element that matches the predicate.
```javascript
A.filter(equal(1), [1, 2, 3])
//=> [ 1 ]
```
<div id="array-find" class="section-name"></div>
`(a -> Boolean) -> Array a -> Maybe a`
Returns the value of the first element that matches the predicate, or `undefined` if it does not exist.
```javascript
A.find(equal(1), [1, 2, 3])
//=> 1
```
<div id="array-findIndex" class="section-name"></div>
`(a -> Boolean) -> Array a -> Number`
Returns the index of the first value that matches the predicate, or -1 if not found.
```javascript
A.findIndex(v => v === 1, [3, 2, 1])
//=> 2
```
<div id="array-get" class="section-name"></div>
`Number -> Array a -> Maybe a`
Retrieves an element of an array by index.
```javascript
A.get(0, [1, 2, 3])
//=> 1
A.get(1, [])
//=> undefined
```
<div id="array-gets" class="section-name"></div>
`Array Number -> Array a -> Array (Maybe a)`
Retrieves multiple elements of an array by index.
```javascript
A.gets([0, 1], [1, 2, 3])
//=> [1, 2]
A.gets([0, 1], [])
//=> [undefined, undefined]
```
<div id="array-groupBy" class="section-name"></div>
`(a -> b) -> Array a -> Object b (Array a)`
Returns an object with keys as the result of applying a function to elements, and the value is an array of every matched element.
```javascript
A.groupBy(Math.floor, [4.2, 6.1, 6.4])
//=> { '4': [ 4.2 ], '6': [ 6.1, 6.4 ] }
```
<div id="array-head" class="section-name"></div>
`Array a -> Maybe a`
Returns the first element in an array.
```javascript
A.head([1, 2, 3, 4, 5])
//=> 1
A.head([])
//=> undefined
```
<div id="array-includes" class="section-name"></div>
`a -> Array a -> Boolean`
Determines if an array contains a value.
```javascript
A.includes('a', ['a', 'b', 'c'])
//=> true
```
<div id="array-indexOf" class="section-name"></div>
`a -> Array a -> Number`
Returns the index of a value, or -1 if not found.
```javascript
A.indexOf(1, [3, 2, 1])
//=> 2
```
<div id="array-init" class="section-name"></div>
`Array a -> Array a`
Returns every element except the last.
```javascript
A.init([1, 2, 3, 4, 5])
//=> [ 1, 2, 3, 4 ]
```
<div id="array-isEmpty" class="section-name"></div>
`Array a -> Boolean`
Determines if an array contains any elements.
```javascript
A.isEmpty([1])
//=> false
```
<div id="array-last" class="section-name"></div>
`Array a -> Maybe a`
Returns the last element in an array.
```javascript
A.last([1, 2, 3, 4, 5])
//=> 5
A.last([])
//=> undefined
```
<div id="array-length" class="section-name"></div>
`Array a -> Number`
Returns the number of elements in an array.
```javascript
A.length([1, 2, 3])
//=> 3
```
<div id="array-map" class="section-name"></div>
`(a -> b) -> Array a -> Array b`
Applies a function over every element in an array.
```javascript
A.map(O.get('a'), [{a: 1}, {a: 2}, {a: 3}])
//=> [ 1, 2, 3 ]
```
<div id="array-max" class="section-name"></div>
`Array a -> Maybe a`
Returns the highest value element in an array.
```javascript
A.max([1, 2, 3])
//=> 3
```
<div id="array-maxBy" class="section-name"></div>
`(a -> b) -> Array a -> Maybe a`
Returns the highest value element in an array.
```javascript
A.maxBy(S.length, ['bc', 'abc', 'a', 'b'])
//=> 'abc'
```
<div id="array-min" class="section-name"></div>
`Array a -> Maybe a`
Returns the lowest value element in an array.
```javascript
A.min([3, 2, 1])
//=> 1
```
<div id="array-minBy" class="section-name"></div>
`(a -> b) -> Array a -> Maybe a`
Returns the lowest value element in an array after applying a function to the element.
```javascript
A.minBy(S.length, ['bc', 'abc', 'a', 'b'])
//=> 'a'
```
<div id="array-partition" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array (a, a)`
Equivalent to `[filter(f, arr), reject(f, arr)]`.
```javascript
A.partition(isEven, [1, 2, 3, 4, 5])
//=> [ [ 2, 4 ], [ 1, 3, 5 ] ]
```
<div id="array-prepend" class="section-name"></div>
`a -> Array a -> Array a`
Adds a value to the beginning of an array.
```javascript
A.prepend(4, [1, 2, 3])
//=> [ 4, 1, 2, 3 ]
A.concat(A.prepend([4, 5], [1, 2, 3]))
//=> [ 4, 5, 1, 2, 3 ]
```
<div id="array-range" class="section-name"></div>
`Number -> Number -> Array Number`
Returns an array of numbers from the start (inclusive) to the end (exclusive).
```javascript
A.range(0, 5)
//=> [ 0, 1, 2, 3, 4 ]
A.range(20, 25)
//=> [ 20, 21, 22, 23, 24 ]
```
<div id="array-reduce" class="section-name"></div>
`(a -> b -> b) -> b -> Array a -> b`
Applies a function over an accumulator and every element in an array, returning the result as a single value.
```javascript
A.reduce(add, 0, [1, 2, 3])
//=> 6
```
<div id="array-reject" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array a`
Returns an array of all elements that do not match the predicate.
```javascript
A.reject(isEven, [1, 2, 3, 4, 5])
//=> [ 1, 3, 5 ]
```
<div id="array-reverse" class="section-name"></div>
`Array a -> Array a`
Returns a new array with the elements in reverse order.
```javascript
A.reverse([1, 2, 3])
//=> [ 3, 2, 1 ]
```
<div id="array-scan" class="section-name"></div>
`(a -> b -> b) -> b -> Array a -> Array b`
Like `reduce`, but returns a list with the initial value, the intermediate values, and the final value.
```javascript
A.scan(add, 0, [1, 2, 3])
//=> [ 0, 1, 3, 6 ]
```
<div id="array-slice" class="section-name"></div>
`Number -> Number -> Array a -> Array a`
Returns a subset of an array, providing starting and ending indexes.
```javascript
A.slice(1, 3, [1, 2, 3, 4, 5])
//=> [ 2, 3 ]
```
<div id="array-some" class="section-name"></div>
`(a -> Boolean) -> Array a -> Boolean`
Determines if any elements match the predicate.
```javascript
A.some(equal(1), [1, 2, 3])
//=> true
```
<div id="array-sort" class="section-name"></div>
`((a, a) -> Number) -> Array a -> Array a`
Returns a sorted array, given a comparison function.
```javascript
A.sort((a, b) => a - b, [5, 39, 1])
//=> [ 1, 5, 39 ]
```
<div id="array-sortBy" class="section-name"></div>
`(a -> b) -> Array a -> Array a`
Sort an array by applying a function to elements.
```javascript
A.sortBy(S.length, ['abc', 'a', 'ab'])
//=> [ 'a', 'ab', 'abc' ]
A.sortBy(O.get('name'), [{ name: 'bob'}, { name: 'alice' }, { name: 'charlie' }])
//=> [ { name: 'alice' }, { name: 'bob' }, { name: 'charlie' } ]
```
<div id="array-sortWith" class="section-name"></div>
`Array ((a -> b) -> a -> a -> Number) -> Array a -> Array a`
Takes an array of comparators, and returns the first non-tie result.
```javascript
const test = A.sortWith([
descendBy(O.get('age')),
ascendBy(O.get('name'))
])
test([{ name: 'charlie', age: 40 }, { name: 'bob', age: 30 }, { name: 'alice', age: 40 }])
//=> [ { name: 'alice', age: 40 }, { name: 'charlie', age: 40 }, { name: 'bob', age: 30 } ]
```
<div id="array-span" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array (a, a)`
Equivalent to `[takeWhile(f, arr), dropWhile(f, arr)]`.
```javascript
A.span(isEven, [2, 4, 5, 6])
//=> [ [ 2, 4 ], [ 5, 6 ] ]
```
<div id="array-tail" class="section-name"></div>
`Array a -> Array a`
Returns every element except the first.
```javascript
A.tail([1, 2, 3, 4, 5])
//=> [ 2, 3, 4, 5 ]
```
<div id="array-take" class="section-name"></div>
`Number -> Array a -> Array a`
Returns the first n elements in an array.
```javascript
A.take(2, [1, 2, 3, 4, 5])
//=> [ 1, 2 ]
```
<div id="array-takeWhile" class="section-name"></div>
`(a -> Boolean) -> Array a -> Array a`
Returns the first elements in an array which match the predicate.
```javascript
A.takeWhile(isEven, [2, 4, 5, 6])
//=> [ 2, 4 ]
```
<div id="array-unique" class="section-name"></div>
`Array a -> Array a`
Returns a list of unique elements.
```javascript
A.unique([1, 1, 1, 3, 5, 5, 9])
//=> [ 1, 3, 5, 9 ]
```
<div id="array-uniqueBy" class="section-name"></div>
`(a -> b) -> Array a -> Array a`
Returns an array of unique values from the applied function.
```javascript
A.uniqueBy(S.length, ['and', 'here', 'are', 'some', 'words'])
//=> [ 'and', 'here', 'words' ]
```
<div id="array-zip" class="section-name"></div>
`Array k -> Array v -> Object k v`
Returns an object, combining an array of keys and an array of values.
```javascript
A.zip(['a', 'b', 'c'], [1, 2, 3, 4])
//=> { a: 1, b: 2, c: 3 }
A.zip(['a', 'b', 'c'], [1, 2])
//=> { a: 1, b: 2 }
```
---
<div id="maybe" class="section-name"></div>
A set of functions for dealing with unwanted values.
```javascript
const Maybe = require('foreword/maybe')
```
<div id="maybe-encase" class="section-name"></div>
`(a -> b) -> a -> Maybe b`
Applies a function that may throw and a value, returns the result or, if it throws, `undefined`.
```javascript
Maybe.encase(x => x.a.b.c, {a: 0})
//=> undefined
Maybe.encase(x => x.a.b.c, {a: {b: {c: 0}}})
//=> 0
```
<div id="maybe-isNothing" class="section-name"></div>
`a -> Boolean`
Determines if a value exists.
```javascript
Maybe.isNothing(null || undefined)
//=> true
Maybe.isNothing(0)
//=> false
```
<div id="maybe-map" class="section-name"></div>
`(a -> Maybe b) -> Maybe a -> Maybe b`
Applies function to value, if value exists, or returns value.
```javascript
Maybe.map(add(1), 1)
//=> 2
Maybe.map(add(1), undefined)
//=> undefined
pipe([
Maybe.map(A.head),
Maybe.map(multiply(2)),
Maybe.map(isEven)
], [])
//=> undefined
```
<div id="maybe-toArray" class="section-name"></div>
`Maybe a -> Array a`
Returns an empty array if value does not exist, or an array with the value.
```javascript
Maybe.toArray(undefined)
//=> []
Maybe.toArray(1)
//=> [1]
```
<div id="maybe-withDefault" class="section-name"></div>
`a -> Maybe a -> a`
Returns the first value, if the second does not exist.
```javascript
Maybe.withDefault(1, undefined)
//=> 1
Maybe.withDefault(1, 10)
//=> 10
```
---
<div id="object" class="section-name"></div>
```javascript
const O = require('foreword/object')
```
<div id="object-concat" class="section-name"></div>
`Array (Object k v) -> Object k v`
Combine an array of objects into one object.
```javascript
O.concat([{ name: 'bob': id: 123 }, { name: 'alice' }, { id: 321 }])
{ name: 'alice', id: 321 }
```
<div id="object-every" class="section-name"></div>
`Object k (v -> Boolean) -> Object k v -> Boolean`
Returns whether every key matches the predicate.
```javascript
const test = O.every({
a: equal('foo'),
b: not(equal('bar')),
x: gt(10),
y: lt(20)
})
test({ a: 'foo', b: 'baz', x: 15, y: 15 })
//=> true
test({ a: 'foo', b: 'baz': x: 10, y: 15 })
//=> false
```
<div id="object-filter" class="section-name"></div>
`Array k -> Object k v -> Object k v`
Returns a subset of an object, with only the specified keys.
```javascript
O.filter(['id', 'name'], { id: 123, name: 'bob', test: 'testing' })
//=> { id: 123, name: 'bob' }
A.map(O.filter(['id']), [{ id: 1, name: 'alice' }, { id: 2, name: 'bob' }])
//=> [ { id: 1 }, { id: 2 } ]
```
<div id="object-find" class="section-name"></div>
`Array k -> Object k v -> Maybe v`
Returns a value from a nested object path.
```javascript
O.find(['a', 'b', 'c'], { a: { b: { c: 1 } } })
//=> 1
```
<div id="object-get" class="section-name"></div>
`k -> Object k v -> Maybe v`
Returns the property of an object, if it exists.
```javascript
O.get('a', { a: 'test' })
//=> 'test'
A.map(O.get('a'), [{ a: 1 }, { a: 2 }, { a: 3 }])
//=> [ 1, 2, 3 ]
```
<div id="object-gets" class="section-name"></div>
`Array k -> Object k v -> Array (Maybe v)`
Returns an array of values where Object k is found.
```javascript
O.gets(['a', 'b'], { a: 1, b: 2 })
//=> [ 1, 2 ]
```
<div id="object-includes" class="section-name"></div>
`k -> Object k v -> Boolean`
Determines if an object contains a key.
```javascript
O.includes('a', { a: 1, b: 2 })
//=> true
```
<div id="object-isEmpty" class="section-name"></div>
`Object k v -> Boolean`
Determines if an object contains any keys.
```javascript
O.isEmpty({})
//=> true
```
<div id="object-length" class="section-name"></div>
`Object k v -> Number`
Returns the number of keys in an object.
```javascript
O.length({ a: 1, b: 2 })
//=> 2
O.length({})
//=> 0
```
<div id="object-map" class="section-name"></div>
`Object k (a -> b) -> Object k a -> Object k b`
Returns an object with transformations applied over specified keys.
```javascript
O.map({ ms: inc }, { id: 123, ms: 999 })
//=> { id: 123, ms: 1000 }
```
<div id="object-reject" class="section-name"></div>
`Array k -> Object k v -> Object k v`
Returns an object, without the keys specified.
```javascript
O.reject(['name', 'test'], { id: 123, name: 'alice', test: 'test' })
//=> { id: 123 }
A.map(O.reject(['id']), [{ id: 1, name: 'alice' }, { id: 2, name: 'bob' }])
//=> [ { name: 'alice' }, { name: 'bob' } ]
```
<div id="object-some" class="section-name"></div>
`Object k (v -> Boolean) -> Object k v -> Boolean`
Returns whether some keys matches the predicate.
```javascript
const test = O.some({
x: gt(10),
y: lt(20)
})
test({ x: 15, y: 25 })
//=> true
test({ x: 5, y: 25 })
//=> false
```
<div id="object-update" class="section-name"></div>
`Object k v -> Object k v -> Object k v`
Creates a new object with values from the first argument merged over the second argument.
```javascript
O.update({ a: true }, { a: false })
//=> { a: true }
```
---
<div id="string" class="section-name"></div>
```javascript
const S = require('foreword/string')
```
<div id="string-append" class="section-name"></div>
`String -> String -> String`
Combine two strings.
```javascript
S.append('ing', 'append')
//=> 'appending'
```
<div id="string-concat" class="section-name"></div>
`Array String -> String`
Combines a list of strings into one string.
```javascript
S.concat(['a', 'b', 'c'])
//=> 'abc'
```
<div id="string-drop" class="section-name"></div>
`Number -> String -> String`
Drops the first n elements in a string.
```javascript
S.drop(3, 'mmmhmmm')
//=> 'hmmm'
```
<div id="string-dropWhile" class="section-name"></div>
`(String -> Boolean) -> String -> String`
Drops the first elements of a string that pass the predicate.
```javascript
S.dropWhile(equal('m'), 'mmmhmm')
//=> 'hmm'
```
<div id="string-includes" class="section-name"></div>
`String -> String -> Boolean`
Determines if a string contains a substring.
```javascript
S.includes('abc', 'abcdef')
//=> true
```
<div id="string-indexOf" class="section-name"></div>
`String -> String -> Number`
Returns the index of a value, or -1 if not found.
```javascript
S.indexOf('abc', 'xyzabc')
//=> 3
```
<div id="string-isEmpty" class="section-name"></div>
`String -> Boolean`
Determines if a string contains any characters.
```javascript
S.isEmpty('abc')
//=> false
```
<div id="string-join" class="section-name"></div>
`String -> Array String -> String`
Joins every element in an array with a string, creating a single string.
```javascript
S.join(':', ['a', 'b', 'c'])
//=> 'a:b:c'
```
<div id="string-length" class="section-name"></div>
`String -> Number`
Returns the number of values in a string.
```javascript
S.length('abc')
//=> 3
```
<div id="string-repeat" class="section-name"></div>
`Number -> String -> String`
Repeated a string n amount of times.
```javascript
S.repeat(3, 'abc')
//=> 'abcabcabc'
```
<div id="string-replace" class="section-name"></div>
`RegExp | String -> String -> String -> String`
Returns a new string with the specified parts replaced.
```javascript
S.replace('foo', 'bar', 'foo foo foo')
//=> 'bar foo foo'
S.replace(/foo/g, 'bar', 'foo foo foo')
//=> 'bar bar bar'
```
<div id="string-reverse" class="section-name"></div>
`String -> String`
Reverses the order of a string.
```javascript
S.reverse('abc')
//=> 'cba'
```
<div id="string-search" class="section-name"></div>
`RegExp -> String -> Number`
Returns the index of the first match from the regular expression, or -1 if not found.
```javascript
S.search(/[A-Z]/g, 'hello World')
//=> 6
```
<div id="string-slice" class="section-name"></div>
`Number -> Number -> String -> String`
Returns a subset of a string, given starting and ending indexes.
```javascript
S.slice(1, 3, 'abcdef')
//=> 'bc'
```
<div id="string-span" class="section-name"></div>
`(String -> Boolean) -> String -> Array (String, String)`
Equivalent to `[takeWhile(f, str), dropWhile(f, str)]`.
```javascript
S.span(equal('m'), 'mmmhmm')
//=> [ 'mmm', 'hmm' ]
```
<div id="string-split" class="section-name"></div>
`String -> String -> Array String`
Splits a string into an array of substrings.
```javascript
S.split(':', 'a:b:c')
//=> [ 'a', 'b', 'c' ]
```
<div id="string-take" class="section-name"></div>
`Number -> String -> String`
Returns the first n elements in a string.
```javascript
S.take(3, 'mmmhmmm')
//=> 'mmm'
```
<div id="string-takeWhile" class="section-name"></div>
`(String -> Boolean) -> String -> String`
Takes the first elements of a string that pass the predicate.
```javascript
S.takeWhile(equal('m'), 'mmmhmm')
//=> 'mmm'
```
<div id="string-toLower" class="section-name"></div>
`String -> String`
Returns an all lowercase string.
```javascript
S.toLower('ABCDEF')
//=> 'abcdef'
```
<div id="string-toUpper" class="section-name"></div>
`String -> String`
Returns an all uppercase string.
```javascript
S.toUpper('abcdef')
//=> 'ABCDEF'
```
<div id="string-trim" class="section-name"></div>
`String -> String`
Removes whitespace from both ends of a string.
```javascript
S.trim(' a \n')
//=> 'a'
```
- [Basics](
- [