Skip to content

Latest commit

 

History

History
1195 lines (833 loc) · 20.3 KB

index.md

File metadata and controls

1195 lines (833 loc) · 20.3 KB

Module iiris

The iiris module contains the core functionality of Iiris. It contains various utility functions that work with a wide variety of data types, while more specialized functions are stored in separate modules. It is designed to be imported with a wildcard, e.g.

import * as I from 'iiris'

Table of contents

Function

binary

<T1, T2, R>(fn: VariadicFunction2<T1, T2, R>) => Function2<T1, T2, R>

Create a version of fn that accepts two arguments.

Note: The returned function is not curried.

Example
const fn = (...args) => args
const wrapped = I.binary(fn)

fn(1, 2, 3)
// => [1, 2, 3]

wrapped(1, 2, 3)
// => [1, 2]

See also: unary


complement

<T extends VariadicFunction0<boolean>>(fn: T) => T

Create a version of a predicate fn that flips the returned boolean value.

Example
const isZero = (v) => v === 0
const notZero = I.complement(isZero)

notZero(0)
// => false

notZero(1)
// => true

compose

<T extends unknown[], R>(fn: (args: ...T) => R) => (args: ...T) => R
<T extends unknown[], T1, R>(fn1: Function1<T1, R>, fn2: (args: ...T) => T1) => (args: ...T) => R
<T extends unknown[], T1, T2, R>(fn1: Function1<T2, R>, fn2: Function1<T1, T2>, fn3: (args: ...T) => T1) => (args: ...T) => R

Right-to-left function composition.

Note: This function is not curried.

Example
const composed = I.compose(I.add(10), I.multiply(2))

composed(2)
// => 14

constant

<T>(value: T) => () => T

Create a function that always returns value.

Example
I.map(I.constant(1), [1, 2, 3])
// => [1, 1, 1]

curry2

<T extends [unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction2<T, R>

Create a curried version of a fn taking two arguments.

Example
const add = I.curry2((a, b) => a + b)

add(1)(2)
// => 3

add(1, 2)
// => 3

See also: curry3, curry4


curry3

<T extends [unknown, unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction3<T, R>

Create a curried version of a fn taking three arguments.

Example
const add = I.curry3((a, b, c) => a + b + c)

add(1)(2)(3)
// => 6

add(1, 2, 3)
// => 6

See also: curry2, curry4


curry4

<T extends [unknown, unknown, unknown, unknown], R>(fn: (args: ...T) => R) => CurriedFunction4<T, R>

Create a curried version of a fn taking four arguments.

Example
const add = I.curry4((a, b, c, d) => a + b + c + d)

add(1)(2)(3)(4)
// => 10

add(1, 2, 3, 4)
// => 10

See also: curry2, curry3


flip

<T, U, R>(fn: Function2<T, U, R>) => Function2<U, T, R>

Flip the arguments of a binary function.

Note: The returned function is not curried.

Example
const fn = (...args) => args
const flipped = I.flip(fn)

flipped(1, 2)
// => [2, 1]

identity

<T>(value: T) => T

Identity function. Returns the first argument.

Example
I.identity(5)
// => 5

noop

() => undefined

Do nothing an return undefined.

Example
I.map(I.noop, [1, 2, 3])
// => [undefined, undefined, undefined]

not

(bool: boolean) => boolean

Logical not. Flip the value of a boolean argument

Example
I.not(true)
// => false

I.not(false)
// => true

See also: complement


pipe

<T>(initial: T) => T
<T, R>(initial: T, fn1: Function1<T, R>) => R
<T1, T2, R>(initial: T1, fn1: Function1<T1, T2>, fn2: Function1<T2, R>) => R

Pipe an initial value through one or more functions in left-to-right order, allowing the programmer to chain operations in a readable manner.

I.pipe(initial, f1, f2, ...fn) can be thought as syntax sugar for fn(...(f2(f1(initial))))

Note: This function is not curried.

Example
I.pipe(
  [1, 2, 3],
  I.map((n) => n * 2),
  I.sum
)
// => 12

See also: compose


tap

<T>(fn: (value: T) => void) => (value: T) => T

Create a function that applies fn to its argument and returns the argument.

Useful for executing a side-effect within a pipeline.

Example
I.pipe(
  [1, 2, 3],
  I.map(I.multiply(2)),
  I.filter(I.gt(2)),
  I.tap(console.log),
  I.sum
)
// Prints: [ 4, 6 ]
// => 10

unary

<T, R>(fn: VariadicFunction1<T, R>) => Function1<T, R>

Create a version of fn that accepts a single argument.

Example
const array = [1, 2, 3]
array.map(I.unary(parseInt))
// => [1, 2, 3]

See also: binary


Logic

maybe

<R>(defaultValue: R) => <T>(fn: (value: T) => R) => (maybeValue: T | undefined) => R

Apply fn to maybeValue if it is not undefined, return defaultValue otherwise.

Example
I.maybe('', (s) => s.toUpperCase(), 'hi')
// => 'HI'

I.maybe('', (s) => s.toUpperCase(), undefined)
// => ''

See also: valueOr


valueOr

<T>(defaultValue: T) => (maybeValue: T | undefined) => T

Return maybeValue if it is not undefined, defaultValue otherwise.

Example
I.valueOr(999, 0)
// => 0

I.valueOr(999, undefined)
// => 999

See also: maybe


Math

add

(n: number) => (m: number) => number

Add two numbers together.

Example
I.map(I.add(1), [1, 2, 3])
// => [2, 3, 4]

dec

(n: number) => number

Decrement a number by 1.

Example
I.map(I.dec, [1, 2, 3])
// => [0, 1, 2]

See also: inc


divideBy

(divisor: number) => (dividend: number) => number

Divide dividend by the divisor.

Example
I.map(I.divideBy(2), [1, 2, 3])
// => [0.5, 1, 1.5]

inc

(n: number) => number

Increment a number by 1.

Example
I.map(I.inc, [1, 2, 3])
// => [2, 3, 4]

multiply

(multiplicand: number) => (multiplier: number) => number

Multiply two numbers together.

Example
I.map(I.multiply(2), [1, 2, 3])
// => [2, 4, 6]

negate

(n: number) => number

Return n with its sign reversed.

Example
I.map(I.negate, [1, 2, 3])
// => [-1, -2, -3]

subtractBy

(subtrahend: number) => (minuend: number) => number

Subtract the subtrahend from the minuend.

Example
I.map(I.subtractBy(1), [1, 2, 3])
// => [0, 1, 2]

Reducing arrays

maximum

<T extends Ordered>(array: T[]) => T | undefined

Return the largest element of an array or undefined.

Example
I.maximum([1, 2, 3])
// => 3

I.maximum([])
// => undefined

See also: minimum, maximumBy


maximumBy

<T, U extends Ordered>(fn: (value: T) => U) => (array: T[]) => T | undefined

Like maximum, but apply fn to each value before determining their ordering.

Example
const users = [
  { name: 'Alice', age: 10 },
  { name: 'Bob', age: 20 },
  { name: 'Carol', age: 30 },
]

I.maximumBy((u) => u.age, users)
// => { name: 'Carol', age: 30 }

See also: maximum, minimumBy


Relation

clamp

<T extends Ordered>(interval: [lower: T, upper: T]) => (value: T) => T

Clamp a number within the closed interval [lower, upper].

Example
I.clamp([0, 10], 5)
// => 5

I.clamp([0, 10], 15)
// => 10

I.clamp([0, 10], -5)
// => 0

equals

<T>(first: T) => (second: T) => boolean

Check if two values are deeply equal.

  • Primitive values are compared with SameValueZero.
  • Only the own enumerable keys of objects are considered.
  • The order of object keys does not matter.
  • Built-in objects (e.g. Arrays, Maps & Sets) are not checked for extra keys.
  • Sets and Map keys are compared with SameValueZero.
  • Error objects are equal if their name and message properties are equal.
  • Functions are compared with ===.
  • Supports cyclic references.
  • Does not support WeakMaps, WeakSets or typed arrays.
Example
I.equals([1, 2, 3], [1, 2, 3])
// => true

I.equals([1, 2, 3], [4, 5, 6])
// => false

equalsBy

<T, U>(fn: (value: T) => U) => (first: T) => (second: T) => boolean

Like equals, but the function fn is applied to both values before determining equality.

Example
I.equalsBy(Math.floor, 1, 1.5)
// => true

See also: equals


gt

<T extends Ordered>(first: T) => (second: T) => boolean

Check if the second argument is greater than the first.

Designed to be used as a curried predicate.

Example
I.filter(I.gt(2), [1, 2, 3])
// => [3]

gte

<T extends Ordered>(first: T) => (second: T) => boolean

Check if the second argument is greater than or equal to the first.

Designed to be used as a curried predicate.

Example
I.filter(I.gte(2), [1, 2, 3])
// => [2, 3]

lt

<T extends Ordered>(first: T) => (second: T) => boolean

Check if the second argument is less than the first.

Designed to be used as a curried predicate.

Example
I.filter(I.lt(2), [1, 2, 3])
// => [1]

lte

<T extends Ordered>(first: T) => (second: T) => boolean

Check if the second argument is less than or equal to the first.

Designed to be used as a curried predicate.

Example
I.filter(I.lte(2), [1, 2, 3])
// => [1, 2]

max

<T extends Ordered>(first: T) => (second: T) => T

Return the larger of two values.

Example
I.max(1, 2)
// => 2

I.max('a', 'b')
// => 'b'

See also: min, maxBy


maxBy

<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => T

Like max, but apply fn to both values before determining their ordering.

Example
I.maxBy(Math.abs, 1, -2)
// => -2

See also: max, minBy


min

<T extends Ordered>(first: T) => (second: T) => T

Return the smaller of two values.

Example
I.min(1, 2)
// => 1

I.min('a', 'b')
// => 'a'

See also: max, minBy


minBy

<T, U extends Ordered>(fn: (value: T) => U) => (first: T) => (second: T) => T

Like min, but apply fn to both values before determining their ordering.

Example
I.minBy(Math.abs, -1, 2)
// => -1

See also: min, maxBy


Sorting

ascend

<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => number

Given a fn that maps a value to an Ordered value, create an ascending comparator function.

Note: The returned function is not curried.

Example
I.sort(I.ascend(I.prop('age')), [{ name: 'Bob' }, { name: 'Alice' }])
// => [{ name: 'Alice' }, { name: 'Bob' }]

See also: descend, sort, sortWith


descend

<T, U extends Ordered>(fn: (value: T) => U) => (first: T, second: T) => number

Given a fn that maps a value to an Ordered value, create a descending comparator function.

Note: The returned function is not curried.

Example
I.sort(I.descend(I.prop('name')), [{ name: 'Alice' }, { name: 'Bob' }])
// => [{ name: 'Bob' }, { name: 'Alice' }]

See also: ascend, sort, sortWith


Type tests

isArray

<T>(value: T | unknown[]) => value is unknown[]

Check if the value is an Array.


isBigInt

<T>(value: T | bigint) => value is bigint

Check if the value is a BigInt.


isBoolean

<T>(value: T | boolean) => value is boolean

Check if the value is a boolean.


isDate

<T>(value: Date | T) => value is Date

Check if the value is a Date.


isDefined

<T>(value: T | undefined) => value is T

Check if the value is not undefined.


isError

<T>(value: Error | T) => value is Error

Check if the value is an Error.


isFunction

<T>(value: Function | T) => value is Function

Check if the value is a function.


isMap

<T>(value: Map<unknown, unknown> | T) => value is Map<unknown, unknown>

Check if the value is a Map.


isNil

<T>(value: T | null | undefined) => value is null | undefined

Check if the value is null or undefined.


isNull

<T>(value: T | null) => value is null

Check if the value is null.


isNumber

<T>(value: T | number) => value is number

Check if the value is a number.


isObject

<T>(value: T | object) => value is object

Check if the value is an object.

Note that functions and arrays are also objects.


isRegExp

<T>(value: RegExp | T) => value is RegExp

Check if the value is a RegExp.


isSet

<T>(value: Set<unknown> | T) => value is Set<unknown>

Check if the value is a Set.


isString

<T>(value: T | string) => value is string

Check if the value is a string.


isSymbol

<T>(value: T | symbol) => value is symbol

Check if the value is a Symbol.


isUndefined

<T>(value: T | undefined) => value is undefined

Check if the value is undefined.