Skip to content

Latest commit

 

History

History
1883 lines (1304 loc) · 33 KB

API.md

File metadata and controls

1883 lines (1304 loc) · 33 KB

API


Basics

const F = require('foreword')
// or
const { add, always, ... } = require('foreword')

add

Number -> Number -> Number

Adds two numbers.

add(2, 2)
//=> 4

always

a -> b -> a

Returns its first argument.

always('a', 'b')
//=> 'a'

and

Boolean -> Boolean -> Boolean

Returns true if both values are true.

and(true, false)
//=> false

ap

Array (a -> b) -> Array a -> Array b

Applies a list of functions over a list of values.

ap([mul(2), add(3)], [1, 2, 3])
//=> [ 2, 4, 6, 4, 5, 6 ]

apply

(a -> b) -> a -> b

Applies function to value.

apply(add(1), 1)
//=> 2

ascend

a -> a -> Number

Takes two comparables and returns a number for sorting in ascending order.

A.sort(ascend, [3, 1, 2])
//=> [ 1, 2, 3 ]

ascendBy

(a -> b) -> a -> a -> Number

Takes a function and applies it over two comparable values for sorting in ascending order.

A.sort(ascendBy(O.get('name')), [{ name: 'bob' }, { name: 'alice' }])
//=> [ { name: 'alice' }, { name: 'bob' } ]

between

Number -> Number -> Number -> Boolean

Determines if a number is between two predicate numbers.

const test = between(0, 10)

test(5)
//=> true

test(20)
//=> false

both

(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.

const test = both(gt(10), lt(20))

test(15)
//=> true

test(30)
//=> false

branch

(a -> Boolean) -> (a -> b) -> (a -> b) -> b

If the predicate is matched, apply the first function, otherwise apply the second.

const test = branch(gt(10), dec, inc)

test(11)
//=> 10

test(9)
//=> 10

clamp

Number -> Number -> Number -> Number

Retricts a number to be within a range.

const test = clamp(1, 10)
test(0)
//=> 1

test(20)
//=> 10

test(5)
//=> 5

complement

(a -> Boolean) -> a -> Boolean

Returns the opposite boolean value that the predicate returned.

complement(equal(1), 1)
//=> false

compose

(b -> c) -> (a -> b) -> a -> c

Applies value through two functions, from right to left.

compose(Math.sqrt, add(1), 99)
//=> 10

curry

Number -> ((a, b) -> c) -> a -> b -> c

Wraps a function and allows you to supply your arguments one at a time.

const add = curry(2, (a, b) => a + b)
const add1 = add(1)
add1(1)
//=> 2

dec

Number -> Number

Decrements a number.

dec(10)
//=> 9

divide

Number -> Number -> Number

Divides two numbers.

divide(2, 10)
//=> 5

descend

a -> a -> Number

Takes two comparables and returns a number for sorting in descending order.

A.sort(descend, [3, 1, 2])
//=> [ 3, 2, 1 ]

descendBy

(a -> b) -> a -> a -> Number

Takes a function and applies it over two comparable values for sorting in descending order.

A.sort(descendBy(O.get('name')), [{ name: 'bob' }, { name: 'alice' }])
//=> [ { name: 'bob' }, { name: 'alice' } ]

either

(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.

const test = either(gt(10), isEven)

test(15)
//=> true

test(5)
//=> false

test(4)
//=> true

equal

a -> a -> Boolean

Returns the result of comparing two values.

equal('abc', 'abc')
//=> true

equal('abc', 'xyz')
//=> false

equalBy

a -> a -> Boolean

Returns the result of comparing two values, after applying a function over the values

equalBy(Math.abs, 5, -5)
//=> true

flip

(a -> b -> c) -> b -> a -> c

Reverses the order of the first two arguments of the provided function.

const gt_ = flip(gt)
gt_(1, 2)
//=> false

gt

a -> a -> Boolean

Determines if a value is greater.

gt(1, 2)
//=> true

gt('a', 'b')
//=> true

gte

a -> a -> Boolean

Determines if a value is greater than or equal.

gte(1, 1)
//=> true

gte(1, 2)
//=> true

id

a -> a

Returns itself.

id('a')
//=> 'a'

A.filter(id, [0, 1, null, 'test'])
//=> [ 1, 'test' ]

inc

Number -> Number

Increments a number.

inc(10)
//=> 11

isEven

Number -> Boolean

Determines if a number is even.

isEven(10)
//=> true

isOdd

Number -> Boolean

Determines if a number is odd.

isOdd(9)
//=> true

lt

a -> a -> Boolean

Determines if a value is lesser.

lt(2, 1)
//=> true

lte

a -> a -> Boolean

Determines if a value is less than or equal.

lte(1, 1)
//=> true

lte(2, 1)
//=> true

match

Array (a -> Maybe b) -> a -> Maybe b

Contains a list of functions that return a value or undefined, working well with when, unless, and branch. Provide a function that always returns a value at the end, to avoid the case where no matches are found.

const fn = match([
  when(lt(10), inc),
  when(gt(10), dec),
  when(always(true), id)
])

fn(1)
//=> 2

fn(15)
//=> 14

fn(10)
//=> 10

max

Number -> Number -> Number

Returns the larger number.

max(4, 9)
//=> 9

min

Number -> Number -> Number

Returns the smaller number.

min(4, 9)
//=> 4

mod

Number -> Number -> Number

Behaves like the mathematical modulo operator.

mod(-20, 3)
//=> 1

multiply

Number -> Number -> Number

Multiplies two numbers.

multiply(2, 5)
//=> 10

negate

Number -> Number

Negated number.

negate(10)
//=> -10

not

Boolean -> Boolean

Returns the opposite boolean value.

not(true)
//=> false

not(A.some(equal(1), [1, 2, 3]))
//=> false

on

(b -> b -> c) -> (a -> b) -> a -> a -> c

Applies a binary function over a unary function twice.

const sameLength = on(equal, S.length)
sameLength('hey', 'now')
//=> true

or

Boolean -> Boolean -> Boolean

Returns true if one or both values are true.

or(true, false)
//=> true

pipe

Array (a -> b) -> a -> b

Applies a sequence of transformations over a value.

pipe([add(1), Math.sqrt], 99)
//=> 10

pow

Number -> Number -> Number

Returns the power.

pow(2, -2)
//=> 4

rem

Number -> Number -> Number

Returns the remainder.

rem(3, -20)
//=> -2

subtract

Number -> Number -> Number

Subtracts two numbers.

subtract(2, 10)
//=> 8

unless

(a -> Boolean) -> (a -> b) -> a -> Maybe b

If the predicate is not matched, run a transformer function, otherwise return undefined.

unless(lt(10), inc, 15)
//=> 16

unless(lt(10), inc, 5)
//=> 5

when

(a -> Boolean) -> (a -> b) -> a -> Maybe b

If the predicate is matched, run a transformer function, otherwise return undefined.

when(lt(10), inc, 5)
//=> 6

Array

const A = require('foreword/array')

append

a -> Array a -> Array a

Adds a value to the end of an array.

A.append(4, [1, 2, 3])
//=> [ 1, 2, 3, 4 ]

A.append([4], [1, 2, 3])
//=> [ 1, 2, 3, [ 4 ] ]

concat

Array a -> Array a

Concatenate an array of arrays into a single array, removing one level of nesting.

A.concat([[1, 2], [3], [4, 5]])
//=> [ 1, 2, 3, 4, 5 ]

concatMap

(a -> Array b) -> Array a -> Array b

Concatenates the result of a map function.

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 ]

countBy

(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.

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 }

drop

Number -> Array a -> Array a

Drops the first n elements in an array.

A.drop(2, [1, 2, 3, 4, 5])
//=> [ 3, 4, 5 ]

dropWhile

(a -> Boolean) -> Array a -> Array a

Drops the first items of an array which match the predicate.

A.dropWhile(isEven, [2, 4, 5, 6])
//=> [ 5, 6 ]

every

(a -> Boolean) -> Array a -> Boolean

Determines if every element satisfies the predicate.

A.every(equal(1), [1, 1, 1])
//=> true

A.every(equal('a'), ['a', 'b', 'c'])
//=> false

filter

(a -> Boolean) -> Array a -> Array a

Returns an array of every element that matches the predicate.

A.filter(equal(1), [1, 2, 3])
//=> [ 1 ]

find

(a -> Boolean) -> Array a -> Maybe a

Returns the value of the first element that matches the predicate, or undefined if it does not exist.

A.find(equal(1), [1, 2, 3])
//=> 1

findIndex

(a -> Boolean) -> Array a -> Number

Returns the index of the first value that matches the predicate, or -1 if not found.

A.findIndex(v => v === 1, [3, 2, 1])
//=> 2

get

Number -> Array a -> Maybe a

Retrieves an element of an array by index.

A.get(0, [1, 2, 3])
//=> 1

A.get(1, [])
//=> undefined

gets

Array Number -> Array a -> Array (Maybe a)

Retrieves multiple elements of an array by index.

A.gets([0, 1], [1, 2, 3])
//=> [1, 2]

A.gets([0, 1], [])
//=> [undefined, undefined]

groupBy

(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.

A.groupBy(Math.floor, [4.2, 6.1, 6.4])
//=> { '4': [ 4.2 ], '6':  [ 6.1, 6.4 ] }

head

Array a -> Maybe a

Returns the first element in an array.

A.head([1, 2, 3, 4, 5])
//=> 1

A.head([])
//=> undefined

includes

a -> Array a -> Boolean

Determines if an array contains a value.

A.includes('a', ['a', 'b', 'c'])
//=> true

indexOf

a -> Array a -> Number

Returns the index of a value, or -1 if not found.

A.indexOf(1, [3, 2, 1])
//=> 2

init

Array a -> Array a

Returns every element except the last.

A.init([1, 2, 3, 4, 5])
//=> [ 1, 2, 3, 4 ]

isEmpty

Array a -> Boolean

Determines if an array contains any elements.

A.isEmpty([1])
//=> false

last

Array a -> Maybe a

Returns the last element in an array.

A.last([1, 2, 3, 4, 5])
//=> 5

A.last([])
//=> undefined

length

Array a -> Number

Returns the number of elements in an array.

A.length([1, 2, 3])
//=> 3

map

(a -> b) -> Array a -> Array b

Applies a function over every element in an array.

A.map(O.get('a'), [{a: 1}, {a: 2}, {a: 3}])
//=> [ 1, 2, 3 ]

max

Array a -> Maybe a

Returns the highest value element in an array.

A.max([1, 2, 3])
//=> 3

maxBy

(a -> b) -> Array a -> Maybe a

Returns the highest value element in an array.

A.maxBy(S.length, ['bc', 'abc', 'a', 'b'])
//=> 'abc'

min

Array a -> Maybe a

Returns the lowest value element in an array.

A.min([3, 2, 1])
//=> 1

minBy

(a -> b) -> Array a -> Maybe a

Returns the lowest value element in an array after applying a function to the element.

A.minBy(S.length, ['bc', 'abc', 'a', 'b'])
//=> 'a'

partition

(a -> Boolean) -> Array a -> Array (a, a)

Equivalent to [filter(f, arr), reject(f, arr)].

A.partition(isEven, [1, 2, 3, 4, 5])
//=> [ [ 2, 4 ], [ 1, 3, 5 ] ]

prepend

a -> Array a -> Array a

Adds a value to the beginning of an array.

A.prepend(4, [1, 2, 3])
//=> [ 4, 1, 2, 3 ]

A.concat(A.prepend([4, 5], [1, 2, 3]))
//=> [ 4, 5, 1, 2, 3 ]

range

Number -> Number -> Array Number

Returns an array of numbers from the start (inclusive) to the end (exclusive).

A.range(0, 5)
//=> [ 0, 1, 2, 3, 4 ]

A.range(20, 25)
//=> [ 20, 21, 22, 23, 24 ]

reduce

(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.

A.reduce(add, 0, [1, 2, 3])
//=> 6

reject

(a -> Boolean) -> Array a -> Array a

Returns an array of all elements that do not match the predicate.

A.reject(isEven, [1, 2, 3, 4, 5])
//=> [ 1, 3, 5 ]

reverse

Array a -> Array a

Returns a new array with the elements in reverse order.

A.reverse([1, 2, 3])
//=> [ 3, 2, 1 ]

scan

(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.

A.scan(add, 0, [1, 2, 3])
//=> [ 0, 1, 3, 6 ]

slice

Number -> Number -> Array a -> Array a

Returns a subset of an array, providing starting and ending indexes.

A.slice(1, 3, [1, 2, 3, 4, 5])
//=> [ 2, 3 ]

some

(a -> Boolean) -> Array a -> Boolean

Determines if any elements match the predicate.

A.some(equal(1), [1, 2, 3])
//=> true

sort

((a, a) -> Number) -> Array a -> Array a

Returns a sorted array, given a comparison function.

A.sort((a, b) => a - b, [5, 39, 1])
//=> [ 1, 5, 39 ]

sortBy

(a -> b) -> Array a -> Array a

Sort an array by applying a function to elements.

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' } ]

sortWith

Array ((a -> b) -> a -> a -> Number) -> Array a -> Array a

Takes an array of comparators, and returns the first non-tie result.

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 } ]

span

(a -> Boolean) -> Array a -> Array (a, a)

Equivalent to [takeWhile(f, arr), dropWhile(f, arr)].

A.span(isEven, [2, 4, 5, 6])
//=> [ [ 2, 4 ], [ 5, 6 ] ]

tail

Array a -> Array a

Returns every element except the first.

A.tail([1, 2, 3, 4, 5])
//=> [ 2, 3, 4, 5 ]

take

Number -> Array a -> Array a

Returns the first n elements in an array.

A.take(2, [1, 2, 3, 4, 5])
//=> [ 1, 2 ]

takeWhile

(a -> Boolean) -> Array a -> Array a

Returns the first elements in an array which match the predicate.

A.takeWhile(isEven, [2, 4, 5, 6])
//=> [ 2, 4 ]

unique

Array a -> Array a

Returns a list of unique elements.

A.unique([1, 1, 1, 3, 5, 5, 9])
//=> [ 1, 3, 5, 9 ]

uniqueBy

(a -> b) -> Array a -> Array a

Returns an array of unique values from the applied function.

A.uniqueBy(S.length, ['and', 'here', 'are', 'some', 'words'])
//=> [ 'and', 'here', 'words' ]

zip

Array k -> Array v -> Object k v

Returns an object, combining an array of keys and an array of values.

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 }

Maybe

A set of functions for dealing with unwanted values.

const Maybe = require('foreword/maybe')

encase

(a -> b) -> a -> Maybe b

Applies a function that may throw and a value, returns the result or, if it throws, undefined.

Maybe.encase(x => x.a.b.c, {a: 0})
//=> undefined

Maybe.encase(x => x.a.b.c, {a: {b: {c: 0}}})
//=> 0

isNothing

a -> Boolean

Determines if a value exists.

Maybe.isNothing(null || undefined)
//=> true

Maybe.isNothing(0)
//=> false

map

(a -> Maybe b) -> Maybe a -> Maybe b

Applies function to value, if value exists, or returns value.

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

toArray

Maybe a -> Array a

Returns an empty array if value does not exist, or an array with the value.

Maybe.toArray(undefined)
//=> []

Maybe.toArray(1)
//=> [1]

withDefault

a -> Maybe a -> a

Returns the first value, if the second does not exist.

Maybe.withDefault(1, undefined)
//=> 1

Maybe.withDefault(1, 10)
//=> 10

Object

const O = require('foreword/object')

concat

Array (Object k v) -> Object k v

Combine an array of objects into one object.

O.concat([{ name: 'bob': id: 123 }, { name: 'alice' }, { id: 321 }])
{ name: 'alice', id: 321 }

every

Object k (v -> Boolean) -> Object k v -> Boolean

Returns whether every key matches the predicate.

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

filter

Array k -> Object k v -> Object k v

Returns a subset of an object, with only the specified keys.

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 } ]

find

Array k -> Object k v -> Maybe v

Returns a value from a nested object path.

O.find(['a', 'b', 'c'], { a: { b: { c: 1 } } })
//=> 1

get

k -> Object k v -> Maybe v

Returns the property of an object, if it exists.

O.get('a', { a: 'test' })
//=> 'test'

A.map(O.get('a'), [{ a: 1 }, { a: 2 }, { a: 3 }])
//=> [ 1, 2, 3 ]

gets

Array k -> Object k v -> Array (Maybe v)

Returns an array of values where Object k is found.

O.gets(['a', 'b'], { a: 1, b: 2 })
//=> [ 1, 2 ]

includes

k -> Object k v -> Boolean

Determines if an object contains a key.

O.includes('a', { a: 1, b: 2 })
//=> true

isEmpty

Object k v -> Boolean

Determines if an object contains any keys.

O.isEmpty({})
//=> true

length

Object k v -> Number

Returns the number of keys in an object.

O.length({ a: 1, b: 2 })
//=> 2

O.length({})
//=> 0

map

Object k (a -> b) -> Object k a -> Object k b

Returns an object with transformations applied over specified keys.

O.map({ ms: inc }, { id: 123, ms: 999 })
//=> { id: 123, ms: 1000 }

reject

Array k -> Object k v -> Object k v

Returns an object, without the keys specified.

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' } ]

some

Object k (v -> Boolean) -> Object k v -> Boolean

Returns whether some keys matches the predicate.

const test = O.some({
  x: gt(10),
  y: lt(20)
})

test({ x: 15, y: 25 })
//=> true

test({ x: 5, y: 25 })
//=> false

update

Object k v -> Object k v -> Object k v

Creates a new object with values from the first argument merged over the second argument.

O.update({ a: true }, { a: false })
//=> { a: true }

String

const S = require('foreword/string')

append

String -> String -> String

Combine two strings.

S.append('ing', 'append')
//=> 'appending'

concat

Array String -> String

Combines a list of strings into one string.

S.concat(['a', 'b', 'c'])
//=> 'abc'

drop

Number -> String -> String

Drops the first n elements in a string.

S.drop(3, 'mmmhmmm')
//=> 'hmmm'

dropWhile

(String -> Boolean) -> String -> String

Drops the first elements of a string that pass the predicate.

S.dropWhile(equal('m'), 'mmmhmm')
//=> 'hmm'

includes

String -> String -> Boolean

Determines if a string contains a substring.

S.includes('abc', 'abcdef')
//=> true

indexOf

String -> String -> Number

Returns the index of a value, or -1 if not found.

S.indexOf('abc', 'xyzabc')
//=> 3

isEmpty

String -> Boolean

Determines if a string contains any characters.

S.isEmpty('abc')
//=> false

join

String -> Array String -> String

Joins every element in an array with a string, creating a single string.

S.join(':', ['a', 'b', 'c'])
//=> 'a:b:c'

length

String -> Number

Returns the number of values in a string.

S.length('abc')
//=> 3

repeat

Number -> String -> String

Repeated a string n amount of times.

S.repeat(3, 'abc')
//=> 'abcabcabc'

replace

RegExp | String -> String -> String -> String

Returns a new string with the specified parts replaced.

S.replace('foo', 'bar', 'foo foo foo')
//=> 'bar foo foo'

S.replace(/foo/g, 'bar', 'foo foo foo')
//=> 'bar bar bar'

reverse

String -> String

Reverses the order of a string.

S.reverse('abc')
//=> 'cba'

search

RegExp -> String -> Number

Returns the index of the first match from the regular expression, or -1 if not found.

S.search(/[A-Z]/g, 'hello World')
//=> 6

slice

Number -> Number -> String -> String

Returns a subset of a string, given starting and ending indexes.

S.slice(1, 3, 'abcdef')
//=> 'bc'

span

(String -> Boolean) -> String -> Array (String, String)

Equivalent to [takeWhile(f, str), dropWhile(f, str)].

S.span(equal('m'), 'mmmhmm')
//=> [ 'mmm', 'hmm' ]

split

String -> String -> Array String

Splits a string into an array of substrings.

S.split(':', 'a:b:c')
//=> [ 'a', 'b', 'c' ]

take

Number -> String -> String

Returns the first n elements in a string.

S.take(3, 'mmmhmmm')
//=> 'mmm'

takeWhile

(String -> Boolean) -> String -> String

Takes the first elements of a string that pass the predicate.

S.takeWhile(equal('m'), 'mmmhmm')
//=> 'mmm'

toLower

String -> String

Returns an all lowercase string.

S.toLower('ABCDEF')
//=> 'abcdef'

toUpper

String -> String

Returns an all uppercase string.

S.toUpper('abcdef')
//=> 'ABCDEF'

trim

String -> String

Removes whitespace from both ends of a string.

S.trim('   a \n')
//=> 'a'