Skip to content

Latest commit

 

History

History
1778 lines (1284 loc) · 46.7 KB

API.md

File metadata and controls

1778 lines (1284 loc) · 46.7 KB

Introduction

Definition of concepts

This library decorates iterables with methods related to lists of values (like find, includes, some, filter...) but taking the oportunity to bring lazy evaluation for them. Then, for better understanding, the API documentation use concepts related to lists instead of iterables. Then, these are the equivalences for a strict definition:

  • An iterable of type a means an iterable that generates values of type a.
  • An iterable of n values or an iterable with length n means an iterable that generates exactly n values.
  • The position or index of value in iterable means the ordinal number in which value is generated by iterable using 0-based numbering.
  • The n-th value of iterable is the value of iterable in the position n.
  • The first n values of iterable are the values between position 0 and n - 1 of iterable.
  • An iterable includes a value means that an iterable generates this value at least in one of its iterations.

Type signature notation

The signature of functions and methods follows an extension of fantasy land notation. In addition,

  • [a] represents an iterable of values of type a.
  • @[a] represents an iterable of values of type a which is an instance of Iterum class.
  • @(a, b) represents an iterable of 2 values whose types are a and b which is an instance of Iterum class.

Iterum example notation

Iterum instances are represented in comments by Lisp list notation to avoid confusion with JavaScript literal objects or arrays. Then, an iterable that iterates over 1, 2, and 3 values is expressed in comments thus:

Iterum([1, 2, 3]) // returns (1 2 3)

If the iterable represented is potentially infinite, the ellipsis is used. For example:

// positive numbers
Iterum.range(1, Infinity) // returns (1 2 3 4...)

Two ways of building iterables

This library provides auto-curried functional and method chaining approach to build iterables. Then, almost of the entries of documentation has two type signatures related to functional and method approach.

API

constructor

constructor :: [a] -> @[a]

It takes an iterable as argument and builds a new Iterum instance which behaves as the same way as the given iterable and is decorated with all of methods that provides Iterum prototype class.

If constructor does not take the arguments defined by the signature specified below, it throws a TypeError.

Constructor can be called using new or not.

Example:

const Iterum = require('iterum')

const array = [1, 2, 3]
const a = Iterum(array) // (1 2 3)
// or with new
const b = new Iterum(array) // (1 2 3)

// spread operator produces the same array regardless how the object is created:
;[...a] // [1, 2, 3]
;[...b] // [1, 2, 3]
;[...array] // [1, 2, 3]

// and Iterum object behaves equal using for..of
let index = 0
for (let val of a) {
    // always vak === array[index]
    ++index
}

// a and b iterables can use Iterum prototype methods
a.map(e => 2 * e) // (2 4 6)
b.filter(e => e === 2) // (1 3)

// constructor can take as argument any iterable:
const stringIterable = Iterum('abc')
const typedArrayIterable = Iterum(Uint8Array([127, 0, 0, 1]))
const setIterable = Iterum(new Set().add(2).add(5).add(6))

chunk

Given an iterable and a number n, it returns a new iterable that split the given iterable into groups of n values.

If chunk method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

chunk :: @[a] ~> Number -> @[@[a]]

Example:

const Iterum = require('iterum')
const {rangeByStep} = Iterum

Iterum([1, 5, 2, 6, 3])
    .chunk(2) // ((1 5) (2 6) (3))
Iterum(rangeByStep(0, Infinity, 2))
    .chunk(4) // ((0 2 4 6) (8 10 12 14) (16 18 20 22)...)
Iterum([1, 2, 3])
    .chunk(true) // throws TypeError
Iterum([1, 2, 3]).chunk(0) // ()

chunk :: Number -> [a] -> @[@[a]]

Example:

const {chunk, rangeByStep} = require('iterum')

chunk(2, [1, 5, 2, 6, 3]) // ((1 5) (2 6) (3))
chunk(4, rangeByStep(0, Infinity, 2)) // ((0 2 4 6) (8 10 12 14) (16 18 20 22)...)
chunk({}, [1, 2, 3]) // throws a TypeError
chunk(2, {name: 'John'}) // throws a TypeError
chunk(0, [1, 2, 3]) // ()

combinations

Given an iterable and a number n, it returns an iterable of iterables that represents the combinations of the iterable values over n.

If combinations method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

combinations :: @[a] ~> Number -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([1, 2, 3, 4]).combinations(2) /* (
    (1 2)
    (1 3)
    (2 3)
    (1 4)
    (2 4)
    (3 4)
) */

Iterum([1, 2, 3, 4]).combinations([]) // throws a TypeError

combinations :: Number -> [a] -> @[@[a]]

Example:

const {combinations} = require('iterum')

combinations(2, [1, 2, 3, 4]) /* (
    (1 2)
    (1 3)
    (2 3)
    (1 4)
    (2 4)
    (3 4)
) */

combinations([], [1, 2, 3, 4]) // throws a TypeError
combinations(2, {one: 1, two: 2, three: 3}) // throws a TypeError

concat

Given two iterables, it returns an iterable which is the concatenation of first iterable with second iterable.

If concat method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

concat :: @[a] ~> [a] -> @[a]

Example:

const Iterum = require('iterum')
const {range} = Iterum

Iterum([0, 0, 0])
    .concat(range(1, Infinity)) // (0 0 0 1 2 3 4...)
Iterum([1, 2, 3])
    .concat('abcd') // (1 2 3 'a' 'b' 'c' 'd')
Iterum([1, 2, 3])
    .concat(4) // throws TypeError

concat :: [a] -> [a] -> @[a]

Example:

const {concat, range} = require('iterum')

concat([0, 0, 0], range(1, Infinity)) // (0 0 0 1 2 3 4...)
concat([1, 2, 3], 'abcd') // (1 2 3 'a' 'b' 'c' 'd')
concat([1, 2, 3], 4) // throws TypeError

cycle

Given an iterable, it returns a new iterable which generates values infinitely based on repetitions of the given iterable.

If cycle method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

cycle :: @[a] ~> () -> @[a]

Example:

const Iterum = require('iterum')

const iterable = Iterum([7, 3, 1])
iterable.cycle() // (7 3 1 7 3 1 7...)

cycle :: [a] -> @[a]

Example:

const {cycle} = require('iterum')

const iterable = [7, 3, 1]
cycle(iterable) // (7 3 1 7 3 1...)
cycle(5) // throws a TypeError

drop

Given an iterable and a number n, it returns a new iterable which excludes the first n values of the given iterable.

If drop method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

drop :: @[a] ~> Number -> @[a]

Example:

const Iterum = require('iterum')
const {rangeByStep} = Iterum

Iterum([1, 5, 2, 6, 3])
    .drop(2) // (2 6 3)
Iterum(rangeByStep(0, Infinity, 2))
    .drop(4) // (8 10 12 14 16...)
Iterum([1, 2, 3])
    .drop(true) // throws TypeError

drop :: Number -> [a] -> @[a]

Example:

const {drop, rangeByStep} = require('iterum')

drop(2, [1, 5, 2, 6, 3]) // (2 6 3)
drop(4, rangeByStep(0, Infinity, 2)) // (8 10 12 14 16...)
drop({}, [1, 2, 3]) // throws a TypeError
drop(2, {name: 'John'}) // throws a TypeError

dropWhile

Given a predicate and iterable, it returns a new iterable which excludes first values of the given iterable such that, applied to the predicate, it returns truthy.

If dropWhile method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

dropWhile :: @[a] ~> (a -> Boolean) -> @[a]

Example:

const Iterum = require('iterum')
const {rangeByStep} = Iterum
const isOdd = num => num % 2 === 1

Iterum([1, 5, 3, 8, 3, 5])
    .dropWhile(isOdd) // (8 3 5)
Iterum(rangeByStep(0, Infinity, 2))
    .dropWhile(isOdd) (0 2 4 6 8...)
Iterum([1, 5, 3, 8, 3, 5])
    .dropWhile(null) // throws a `TypeError`

dropWhile :: (a -> Boolean) -> [a] -> @[a]

Example:

const Iterum = require('iterum')
const {rangeByStep} = Iterum
const isOdd = num => num % 2 === 1

Iterum([1, 5, 3, 8, 3, 5])
    .dropWhile(isOdd) // (8 3 5)
Iterum(rangeByStep(0, Infinity, 2))
    .dropWhile(isOdd) (0 2 4 6 8...)
Iterum([1, 5, 3, 8, 3, 5])
    .dropWhile(null) // throws a `TypeError`

entries

Given iterable, it returns a new iterable of entries. An entry is an iterable of 2 values (index value) where value is the value that generates the given iterable and index is the position of value in the iterable.

entries :: @[a] ~> () -> @[@(Number, a)]

Example:

const Iterum = require('iterum')

Iterum('abc')
    .entries() // ((0 'a') (1 'b') (2 'c'))
Iterum(new Set(['foo', 'bar', 'fizz', 'buzz']))
    .entries() // ((0 'foo') (1 'bar') (2 'fizz') (3 'buzz'))

entries :: [a] -> @[@(Number, a)]

Example:

const {entries} = require('iterum')

entries('abc') // ((0 'a') (1 'b') (2 'c'))
entries(new Set(['foo', 'bar', 'fizz', 'buzz']) // ((0 'foo') (1 'bar') (2 'fizz') (3 'buzz'))

every

Given iterable, it checks if predicate returns truthy for all of values of iterable. Iteration is truncated returning false once predicate returns falsey.

If every method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

every :: @[a] ~> (a -> Boolean) -> Boolean

Example:

const Iterum = require('iterum')

Iterum([1, 2, 3])
    .every(num => num < 5) // true
Iterum([1, 2, 3])
    .every(num => num > 0) // false
Iterum([1, 2, 3])
    .every([4, 5, 6]) // throws a TypeError

every :: (a -> Boolean) -> [a] -> Boolean

Example:

const {every} = require('iterum')

every(num => num < 5, [1, 2, 3]) // true
every(num => num > 0, [1, 2, 3]) // false
every([4, 5, 6], [1, 2, 3]) // throws a TypeError
every([4, 5, 6], true) // throws a TypeError

filter

Given an iterable and a predicate, it returns a new iterable that generates the values of the given iterable such that, applied to the predicate, it returns truthy.

If filter method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

filter :: @[a] ~> (a -> Boolean) -> @[a]

Example:

const Iterum = require('iterum')
const {range} = Iterum

Iterum([1, 7, 2, 9, 8, 2, 4])
    .filter(num => num < 5) // (1 2 2 4)
range(0, Infinity)
    .filter(num => num % 2 === 0) // (0 2 4 6 8...)

find

Given an iterable and a predicate, it iterates over elements of iterable, returning the first element predicate returns truthy for. If the predicate does not return truthy for any value, find returns undefined.

If find method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

find :: @[a] ~> (a -> Boolean) -> a

Example:

const Iterum = require('iterum')

const iterable = Iterum([1, 8, 3, 4]) // (1 8 3 4)

iterable.find(num => num % 4 === 0) // 8
iterable.find(num => num % 4 === 2) // undefined
iterable.find(3) // throws a TypeError

find (a -> Boolean) -> [a] -> a

Example:

const {find} = require('iterum')

const iterable = [1, 8, 3, 4]

find(num => num % 4 === 0, iterable) // 8
find(num => num % 4 === 2, iterable) // undefined
find(3, iterable) // throws a TypeError
find(num => num % 4 === 2, 4) // throws a TypeError

findEntry

Given an iterable and a predicate, it iterates over elements of iterable, returning the entry of first element predicate returns truthy for. If the predicate does not return true for any value, findEntry returns undefined.

If findEntry method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

findEntry :: @[a] ~> (a -> Boolean) -> @(Number, a)

Example:

const Iterum = require('iterum')

const iterable = Iterum([1, 8, 3, 4])

iterable.findEntry(num => num % 4 === 0) // [1, 8]
iterable.findEntry(num => num % 4 === 2) // undefined
iterable.findEntry(3) // throws a TypeError

findEntry :: @[a] ~> (a -> Boolean) -> @(Number, a)

Example:

const Iterum = require('iterum')

const iterable = Iterum([1, 8, 3, 4])

iterable.findEntry(num => num % 4 === 0) // (1 8)
iterable.findEntry(num => num % 4 === 2) // undefined
iterable.findEntry(3) // throws a TypeError

findEntry :: (a -> Boolean) -> [a] -> @(Number, a)

Example:

const {findEntry} = require('iterum')

const iterable = [1, 8, 3, 4]

findEntry(num => num % 4 === 0, iterable) // (1 8)
findEntry(num => num % 4 === 2, iterable) // undefined
findEntry(3, iterable) // throws a TypeError
findEntry(num => num % 4 === 0, 4) // throws a TypeError

findIndex

Given an iterable and a predicate, it iterates over elements of iterable, returning the position of first element predicate returns truthy for. If the predicate does not return true for any value, findIndex returns -1.

If findIndex method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

findIndex :: @[a] ~> (a -> Boolean) -> Number

Example:

const Iterum = require('iterum')

const iterable = Iterum([1, 8, 3, 4])

iterable.findIndex(num => num % 4 === 0) // 1
iterable.findIndex(num => num % 4 === 2) // -1
iterable.findIndex(3) // throws a TypeError

findIndex :: (a -> Boolean) -> [a] -> Number

Example:

const {findIndex} = require('iterum')

const iterable = Iterum([1, 8, 3, 4])

findIndex(num => num % 4 === 0, iterable) // 1
findIndex(num => num % 4 === 2, iterable) // -1
findIndex(3, iterable) // throws a TypeError
findIndex(num => num % 4 === 2, true) // throws a TypeError

flatten

Given an iterable and a depth, it returns a new iterable that is flattened up to depth.

If flatten method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

flatten :: @[a] ~> Number -> @[b]

Example:

const Iterum = require('iterum')

const iterable = Iterum([['abc', ['def']], 3]) // (['abc', ['def']] 3)
iterable.flatten(0) // (['abc', ['def']] 3)
iterable.flatten(1) // ('abc' ['def'] 3)
iterable.flatten(2) // ('a' 'b' 'c' 'def' 3)
iterable.flatten(3) // ('a' 'b' 'c' 'd' 'e' 'f' 3)
iterable.flatten(Infinity) // ('a' 'b' 'c' 'd' 'e' 'f' 3)
iterable.flatten('abc') // throws a TypeError

flatten :: Number -> [a] -> @[b]

Example:

const {flatten} = require('iterum')

const iterable = [['abc', ['def']], 3]
flatten(0, iterable) // (['abc', ['def']] 3)
flatten(1, iterable) // ('abc' ['def'] 3)
flatten(2, iterable) // ('a' 'b' 'c' 'def' 3)
flatten(3, iterable) // ('a' 'b' 'c' 'd' 'e' 'f' 3)
flatten(Infinity, iterable) // ('a' 'b' 'c' 'd' 'e' 'f' 3)
flatten('abc', iterable) // throws a TypeError
flatten(1, {fizz: 'buzz', foo: 'bar'}) // throws a TypeError

groupBy

Given an iterable and a function f, it returns an iterable which iterates over groups of values such that f returns the same value. The order of grouped values is determined by the order they occur in iterable. Two values x and y of given iterable are in the same group if sameValueZero(f(x), f(y)) returns true.

If groupBy method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

groupBy :: @[a] ~> (a -> b) -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([1, 2, 3, 4, 5, 6, 7])
    .groupBy(e => e % 3) // ((1 4 7) (2 5) (3 6))
Iterum(['abc', '1.9', '2.5', '2', 'cba'])
    .groupBy(parseInt) // (('abc' 'cba') ('1.9') ('2.5' '2'))

groupBy :: (a -> b) -> [a] -> @[@[a]]

Example:

const {groupBy} = require('iterum')

groupBy(e => e % 3, [1, 2, 3, 4, 5, 6, 7]) // ((1 4 7) (2 5) (3 6))
groupBy(parseInt, ['abc', '1.9', '2.5', '2', 'cba']) // (('abc' 'cba') ('1.9') ('2.5' '2'))

has

Given an iterable and a number n, it returns true or false if iterable generates a n-th value or not.

If has method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

has :: @[a] ~> Number -> Boolean

Example:

const Iterum = require('iterum')
const {range} = Iterum

Iterum([7, 6, 5])
    .has(2) // true
Iterum([7, 6, 5])
    .has(3) // false
range(-5, Infinity)
    .has(10000) // true
range(-5, Infinity)
    .has(-1) // false
Iterum([1, 2, 3])
    .has('a') // throws TypeError

has :: Number -> [a] -> Boolean

Example:

const {has, range} = require('iterum')

has(2, [7, 6, 5]) // true
has(3, [7, 6, 5]) // false
has(10000, range(-5, Infinity)) // true
has(-1, range(-5, Infinity)) // false
has('a', [1, 2, 3]) // throws TypeError

includes

Given an iterable and a value, it returns true if iterable includes this value. Values are compared using the sameValueZero specification.

If includes method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

includes :: @[a] ~> a -> Boolean

Example:

const Iterum = require('iterum')

Iterum([1, 4, 3, 5, 3])
    .includes(3) // true
Iterum([1, 4, 3, 5, 3])
    .includes(100) // false
Iterum([1, 4, NaN, 5, 3])
    .includes(NaN) // true

includes :: a -> [a] -> Boolean

Example:

const {includes} = require('iterum')

includes(3, [1, 4, 3, 5, 3]) // true
includes(100, [1, 4, 3, 5, 3]) // false
includes(NaN, [1, 4, NaN, 5, 3]) // true
includes(3, /a+/) // throw a TypeError

indexOf

Given an iterable and a value, it returns a number that means the position of first value that is equal to val in iterable iteration. If iterable does not iterate over this value, indexOf returns -1. Values are compared using the sameValueZero specification.

If indexOf method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

indexOf :: @[a] ~> a -> Number

Example:

const Iterum = require('iterum')

Iterum([1, 4, 3, 5, 3])
    .indexOf(3) // 2
Iterum([1, 4, 3, 5, 3])
    .indexOf(100) // -1
Iterum([1, 4, NaN, 5, 3])
    .indexOf(NaN) // 2

indexOf :: a -> [a] -> Number

Example:

const {indexOf} = require('iterum')

indexOf(3, [1, 4, 3, 5, 3]) // 2
indexOf(100, [1, 4, 3, 5, 3]) // -1
indexOf(NaN, [1, 4, NaN, 5, 3]) // 2
indexOf(2, {a: 1, b: 2}) // throws a TypeError

indexOfFrom

Given an iterable, a value val and a number n, it returns the position of first value that is equal to val in iterable iteration starting to search from value on n position. If iterable does not iterate over this value, it returns -1. Values are compared using the sameValueZero specification.

If indexOfFrom method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

indexOfFrom :: @[a] ~> (a, Number) -> Number

Example:

const Iterum = require('iterum')

Iterum([1, 3, 4, 5, 3])
    .indexOfFrom(3, 2) // 4
Iterum('aaabbbbb')
    .indexOfFrom('a', 3) // -1
Iterum([1, NaN, 2, NaN, 3])
    .indexOfFrom(NaN, 2) // 3
Iterum([1, NaN, 2, NaN, 3])
    .indexOfFrom(NaN, []) // throws a TypeError

indexOfFrom :: a -> Number -> [a] -> Number

Example:

const {indexOfFrom} = require('iterum')

indexOfFrom(3, 2, [1, 3, 4, 5, 3]) // 2
indexOfFrom('a', 3, 'aaabbbbb') // -1
indexOfFrom(NaN, 2, [1, NaN, 2, NaN, 3]) // 3
indexOfFrom(NaN, [], [1, NaN, 2, NaN, 3]) // throws a TypeError
indexOfFrom(2, 1, {a: 1, b: 2}) // throws a TypeError

isEqual

Given two iterables, it returns true if iterables are equivalent and otherwise, false. Equality of iterables is determined comparing value by value using sameValueZero specification for comparisons. If iterables do not generate the same number of values, it returns false.

If isEqual method or function does not take the arguments defined by the signatures specified below, it returns false.

isEqual :: @[a] ~> [a] -> Boolean

Example:

const Iterum = require('iterum')

const iterable = Iterum([NaN, 0, 2, 3])

iterable.isEqual(new Set([NaN, -0, 2, 3])) // true
iterable.isEqual([NaN, 0, 2, 3, 5]) // false
iterable.isEqual([NaN, 0, 5, 3]) // false
iterable.isEqual(3) // false

isEqual :: [a] -> [a] -> Boolean

Example:

const {isEqual} = require('iterum')

const iterable = [NaN, 0, 2, 3]

isEqual(iterable, new Set([NaN, -0, 2, 3])) // true
isEqual(iterable, [NaN, 0, 2, 3, 5]) // false
isEqual(iterable, [NaN, 0, 5, 3]) // false
isEqual(3, 3) // false
isEqual(2, null) // false

isEqualBy

Given two iterables and a function f, it returns true if iterables are equivalent and otherwise, false. Equality of iterables is determined comparing value by value using (a, b) => sameValueZero(f(a), f(b)) comparation. If iterables do not generate the same number of values, it returns false.

If isEqualBy method or function does not take the arguments defined by the signatures specified below, it returns false.

isEqualBy :: @[a] ~> (a -> b, [a]) -> Boolean

Example:

const Iterum = require('iterum')

const iterable = Iterum(['abc', '2.3'])

iterable.isEqualBy(parseInt, ['cba', '2.1']) // true
iterable.isEqualBy(e => e.length, ['cba']) // false
iterable.isEqualBy(e => e.length, ['abc', '1.9']) // true
iterable.isEqualBy(parseInt, ['abc', '1.9']) // false

isEqualBy :: (a -> b) -> [a] -> [a] -> Boolean

Example:

const {isEqualBy} = require('iterum')

const iterable = Iterum(['abc', '2.3'])

isEqualBy(parseInt, iterable, ['cba', '2.1']) // true
isEqualBy(e => e.length, iterable, ['cba']) // false
isEqualBy(e => e.length, iterable, ['abc', '1.9']) // true
isEqualBy(parseInt, iterable, ['abc', '1.9']) // false

isEqualWith

Given two iterables and binary predicate, it returns true if iterables are equivalent and otherwise, false. Equality of iterables is determined value by value using the given predicate for comparisons. If iterables do not generate the same number of values, it returns false.

If isEqualWith method or function does not take the arguments defined by the signatures specified below, it returns false.

isEqualWith :: @[a] ~> (a -> Boolean, [a]) -> Boolean

Example:

const Iterum = require('iterum')

const iterable = Iterum(['abc', NaN])

iterable.isEqualWith((a, b) => typeof a === typeof b, ['cba', 3]) // true
iterable.isEqualWith((a, b) => a === b, ['abc', NaN]) // false

isEqualWith :: (a -> Boolean) -> [a] -> [a] -> Boolean

Example:

const {isEqualWith} = require('iterum')

const iterable = Iterum(['abc', NaN])

isEqualWith((a, b) => typeof a === typeof b, iterable, ['cba', 3]) // true
isEqualWith((a, b) => a === b, iterable, ['abc', NaN]) // false

isEmpty

Given an iterable, it returns true if iterable does not generate values. Otherwise it returns false.

If isEmpty method or function does not take the arguments defined by the signatures specified below, it returns false.

isEmpty :: @[a] ~> () -> Boolean

Example:

const Iterum = require('iterum')

Iterum([7, 1, 3]).isEmpty() // false
Iterum([]).isEmpty() // true
Iterum('').isEmpty() // true
Iterum(new Set()).isEmpty() // true

isEmpty :: [a] -> Boolean

Example:

const {isEmpty} = require('iterum')

isEmpty([7, 1, 3]) // false
isEmpty([]) // true
isEmpty('') // true
isEmpty(new Set()) // true
isEmpty(5) // throws a TypeError

map

Given an iterable and a function, it returns a new iterable that generates values based on apply the given function to each value of the given iterable.

If map method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

map :: @[a] ~> (a -> b) -> @[b]

Example:

const Iterum = require('iterum')
const {range} = Iterum

Iterum([7, 3, 1, 4])
    .map(num => 3 * num) // (21 9 3 12)
range(0, Infinity)
    .map(num => 2 * num) // (0 2 4 6 8...)
Iterum([7, 3, 1, 4])
    .map(8) // throws a TypeError

map :: (a -> b) -> [a] -> @[b]

Example:

const {map, range} = require('iterum')

map(num => 3 * num, [7, 3, 1, 4]) // (21 9 3 12)
map(num => 2 * num, range(0, Infinity)) // (0 2 4 6 8...)
map(8, [7, 3, 1, 4]) // throws a TypeError
map(num => 3 * num, 8) // throws a TypeError

nth

Given an iterable and a number n, it returns the n-th value of iterable. If n-th value does not exist it returns undefined

If nth method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

nth :: @[a] ~> Number -> (a | undefined)

Example:

const Iterum = require('iterum')
const {range} = Iterum

Iterum([7, 6, 5])
    .nth(2) // 5
Iterum([7, 6, 5])
    .nth(3) // undefined
range(-5, Infinity)
    .nth(10000) // 9995
range(-5, Infinity)
    .nth(-1) // undefined
Iterum([1, 2, 3])
    .nth('a') // throws TypeError

nth :: Number -> [a] -> (a | undefined)

Example:

const {nth, range} = require('iterum')

nth(2, [7, 6, 5]) // 5
nth(3, [7, 6, 5]) // undefined
nth(10000, range(-5, Infinity)) // 9995
nth(-1, range(-5, Infinity)) // undefined
nth('a', [1, 2, 3]) // throws TypeError

padEnd

Given an iterable, a number length and a value, it returns a new iterable that iterates over the same values as the given iterable and if it generates less values than length, it continues generating value values until generating length values.

If padEnd method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

padEnd :: @[a] ~> @(Number, a) -> @[a]

Example:

const Iterum = require('iterum')

const iterable = Iterum([3, 2, 8]) // (3 2 8)
iterable.padEnd(5, 0) // (3 2 8 0 0)
iterable.padEnd(7, 1) // (3 2 8 1 1 1 1)
iterable.padEnd(3, 0) // (3 2 8)
iterable.padEnd(0, 5) // (3 2 8)
iterable.padEnd(Infinity, 2) // (3 2 8 2 2 2 2...)

padEnd :: Number -> a -> [a] -> @[a]

Example:

const {padEnd} = require('iterum')

const iterable = [3, 2, 8]
padEnd(5, 0, iterable) // (3 2 8 0 0)
padEnd(7, 1, iterable) // (3 2 8 1 1 1 1)
padEnd(3, 0, iterable) // (3 2 8)
padEnd(0, 5, iterable) // (3 2 8)
padEnd(Infinity, 2, iterable) // (3 2 8 2 2 2 2...)

permutations

Given an iterable, it returns a new iterable that iterates over all its permutations.

If permutations method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

permutations :: @[a] ~> () -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([3, 2, 1])
    .permutations() /* (
        (3 2 1)
        (2 3 1)
        (3 1 2)
        (1 3 2)
        (2 1 3)
        (1 2 3)
    ] */

permutations :: [a] -> @[@[a]]

Example:

const {permutations} = require('iterum')

permutations([3, 2, 1]) /* (
    (3 2 1)
    (2 3 1)
    (3 1 2)
    (1 3 2)
    (2 1 3)
    (1 2 3)
] */

power

Given an iterable and a number, it returns the cartesian power of the given iterable.

If power method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

power :: @[a] ~> Number -> @[@[a]]

Example:

const Iterum = require('iterum')

// the same as Iterum([[0, 1, 2], [0, 1, 2]]).product()
Iterum([0, 1, 2]).power(2) /* (
    (0 0)
    (1 0)
    (2 0)
    (0 1)
    (1 1)
    (2 1)
    (0 2)
    (1 2)
    (2 2)
) */
// the same as Iterum([[0, 1], [0, 1], [0, 1]]).product()
Iterum([0, 1]).power(3) /* (
    (0 0 0)
    (1 0 0)
    (0 1 0)
    (1 1 0)
    (0 0 1)
    (1 0 1)
    (0 1 1)
    (1 1 1)
) */
// infinity power
Iterum([0, 1]).power(Infinity) /* (
    (0 0 0...)
    (1 0 0...)
    (0 1 0...)
    (1 1 0...)
    (0 0 1...)
    .
    .
    .
) */

power :: Number -> [a] -> @[@[a]]

Example:

const {power} = require('iterum')

// the same as product([[0, 1, 2], [0, 1, 2]])
power(2, [0, 1, 2]) /* (
    (0 0)
    (1 0)
    (2 0)
    (0 1)
    (1 1)
    (2 1)
    (0 2)
    (1 2)
    (2 2)
) */
// the same as product([[0, 1], [0, 1], [0, 1]])
power(3, [0, 1]) /* (
    (0 0 0)
    (1 0 0)
    (0 1 0)
    (1 1 0)
    (0 0 1)
    (1 0 1)
    (0 1 1)
    (1 1 1)
) */
// infinity power
power(Infinity, [0, 1]) /* (
    (0 0 0...)
    (1 0 0...)
    (0 1 0...)
    (1 1 0...)
    (0 0 1...)
    .
    .
    .
) */

powerSet

Given an iterable, it returns the power set of the given iterable.

If powerSet method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

powerSet :: @[a] ~> () -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([5, 2]).powerSet() /* (
    ()
    (5)
    (2)
    (5 2)
) */
Iterum([1, 2, 3]).powerSet() /* (
    ()
    (1)
    (2)
    (3)
    (1 2)
    (1 3)
    (2 3)
    (1 2 3)
) */

powerSet :: [a] -> @[@[a]]

Example:

const {powerSet} = require('iterum')

powerSet([5, 2]) /* (
    ()
    (5)
    (2)
    (5 2)
) */
powerSet([1, 2, 3]) /* (
    ()
    (1)
    (2)
    (3)
    (1 2)
    (1 3)
    (2 3)
    (1 2 3)
) */

product

Given an iterable of iterables, it returns the cartesian product of these iterables.

If product method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

product :: @[@[a]] ~> () -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([
    [6, 3],
    'abc',
    [1]
]).product() /* (
    (6 'a' 1)
    (6 'b' 1)
    (6 'c' 1)
    (3 'a' 1)
    (3 'b' 1)
    (3 'c' 1)
) */

product :: [[a]] -> @[@[a]]

Example:

const {product} = require('iterum')

product([
    [6, 3],
    'abc',
    [1]
]) /* (
    (6 'a' 1)
    (6 'b' 1)
    (6 'c' 1)
    (3 'a' 1)
    (3 'b' 1)
    (3 'c' 1)
) */

range

Given start number and end number, it returns an iterable that iterates over values between start and end values both included with a step 1.

If rangefunction does not take the arguments defined by the signature specified below, it throws a TypeError.

range :: Number -> Number -> @[a]

Example:

const {range} = require('iterum')

range(2, 7) // (2 3 4 5 6 7)
range(-5, 0) // (-5 -4 -3 -2 -1 0)
range(5, 0) // ()
range(1, Infinity) // (1 2 3 4 5...)

rangeByStep

Given start number, end number and step number, it returns an iterable that iterates over values between start and end values both included with the given step.

If rangeByStep function does not take the arguments defined by the signature specified below, it throws a TypeError.

rangeByStep :: Number -> Number -> @[a]

Example:

const {rangeByStep} = require('iterum')

rangeByStep(2, 12, 3) // (2 5 8 11)
rangeByStep(5, 1, -1) // (5 4 3 2 1)
rangeByStep(1, Infinity, 2) // (1 3 5 7 9...)

reduce

Given an iterable, a binary function and an initial value, it reduces the given iterable from left to right with the binary function starting with the given initial value as accumulator.

If reduce method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

reduce :: @[a] ~> ((b, a) -> b, b) -> b

Example:

const Iterum = require('iterum')

Iterum([5, 2, 1])
    .reduce((x, y) => x - y, 0) // 0 - 5 - 2 - 1 === 2

reduce :: ((b, a) -> b) -> b -> [a] -> b

Example:

const {reduce} = require('iterum')

reduce((x, y) => x - y, 0, [5, 2, 1]) // 0 - 5 - 2 - 1 === 2

reduceRight

Given an iterable, a binary function and an initial value, it reduces the given iterable from right to left with the binary function starting with the given initial value as accumulator.

If reduceRight method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

reduceRight :: @[a] ~> ((b, a) -> b, b) -> b

Example:

const Iterum = require('iterum')

Iterum([5, 2, 1])
    .reduceRight((x, y) => x - y, 0) // 0 - 1 - 2 - 5 === -8

reduceRight :: ((b, a) -> b) -> b -> [a] -> b

Example:

const {reduceRight} = require('iterum')

reduceRight((x, y) => x - y, 0, [5, 2, 1]) // 0 - 1 - 2 - 5 === -8

repeat

Given an iterable and a number n, it returns a new iterable that iterates over all values generated by the iterable for n times.

If repeat method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

repeat :: @[a] ~> Number -> @[a]

Example:

const Iterum = require('iterum')

const iterable = Iterum([7, 3, 1])
iterable.repeat(4) // (7 3 1 7 3 1 7 3 1 7 3 1)
iterable.repeat(Infinity) // (7 3 1 7 3 1...)
iterable.repeat('a') // throws a TypeError

repeat :: Number -> [a] -> @[a]

Example:

const {repeat} = require('iterum')

const iterable = [7, 3, 1]
repeat(4, iterable) // (7 3 1 7 3 1 7 3 1 7 3 1)
repeat(Infinity, iterable) // (7 3 1 7 3 1...)
repeat('a', iterable) // throws a TypeError

slice

Given an iterable, a start number and end number, it returns a new iterable that iterates over all values produced by the given iterable between start and end positions, end not included.

If slice method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

slice :: @[a] ~> (Number, Number) -> @[a]

Example:

const Iterum = require('iterum')
const {range} = Iterum

range(5, Infinity)
    .slice(1, 4) // (6 7 8)

slice :: Number -> Number -> [a] -> @[a]

Example:

const {range, slice} = require('iterum')

slice(1, 4, range(5, Infinity)) // (6 7 8)

some

Given an iterable and a predicate, it checks if predicate returns truthy for any value that generates the iterable. Iteration is truncated returning true once predicate returns truthy.

If some method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

some :: @[a] ~> (a -> Boolean) -> Boolean

Example:

const Iterum = require('iterum')

Iterum([0, 1, 2])
    .some(num => num === 1) // true
Iterum([0, 1, 2])
    .some(num => num === -2) // false
Iterum([0, 1, 2])
    .some({}) // throws a TypeError

some :: (a -> Boolean) -> [a] -> Boolean

Example:

const Iterum = require('iterum')

some(num => num === 1, [0, 1, 2]) // true
some(num => num === -2, [0, 1, 2]) // false
some({}, [0, 1, 2]) // throws a TypeError

take

Given an iterable and a number n, it returns a new iterable that iterates over the n first values of the given iterable.

If take method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

take :: @[a] ~> Number -> @[a]

Example:

const Iterum = require('iterum')
const {range} = Iterum

range(1, 2000)
    .take(3) // (1 2 3)

take :: Number -> [a] -> @[a]

Example:

const {take, range} = require('iterum')

take(3, range(1, 2000)) // (1 2 3)

takeWhile

Given a predicate and an iterable, it returns a new iterable that iterates over the first values of the given iterable such that, applied to the predicate, it returns truthy.

If takeWhile method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

takeWhile :: @[a] ~> (a -> Boolean) -> @[a]

Example:

const Iterum = require('iterum')

const iterable = Iterum([2, 5, 8, 10, 9, 8, 7, 6, 5, 4])

iterable.takeWhile(num => num % 3 === 2) // (2 5 8)
iterable.takeWhile(null) // throws a TypeError

takeWhile :: (a -> Boolean) -> [a] -> @[a]

Example:

const {takeWhile} = require('iterum')

const iterable = [2, 5, 8, 10, 9, 8, 7, 6, 5, 4]

takeWhile(num => num % 3 === 2, iterable) // (2 5 8)
takeWhile(null, iterable) // throws a TypeError
takeWhile(num => num % 3 === 2, {}) // throws a TypeError

tap

Given an iterable and a function, it returns an equivalent iterable. The given function is only useful for debugging or doing side effects.

If tap method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

tap :: @[a] ~> (a -> b) -> @[a]

Example:

const Iterum = require('iterum')
const log = console.log.bind(console)

const iterable = Iterum([1, 2, 3, 4])
    .filter(e => e !== 3)
    .tap(log)
    .map(e => 2 * e) // (2 4 8)

;[...iterable] /*
output:
1
2
4
*/

tap :: (a -> b) -> [a] -> @[a]

Example:

const Iterum = require('iterum')
const log = console.log.bind(console)

const iterable = map(e => 2 * e,
    tap(log,
        filter(e => e !== 3, [1, 2, 3, 4])))

;[...iterable] /*
output:
1
2
4
*/

toString

Given an iterable, it returns a string representation of the given iterable. It cuts the iterable and puts ellipsis if its length is greater than 10.

If toString method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

toString :: @[a] ~> () -> String

Example:

const {range} = require('iterum')

const oneToFour = range(1, 4)
const oneToInfinity = range(1, Infinity)

oneToFour.toString() // '(1 2 3 4)'
`${oneToFour}` // '(1 2 3 4)'
oneToInfinity.toString() // '(1 2 3 4 5 6 7 8 9 10...)'
`${oneToInfinity}` // '(1 2 3 4 5 6 7 8 9 10...)'

toString :: [a] -> String

Example:

const {range, toString} = require('iterum')

const oneToFour = range(1, 4)
const oneToInfinity = range(1, Infinity)

toString(oneToFour) // '(1 2 3 4)'
toString(oneToInfinity) // '(1 2 3 4 5 6 7 8 9 10...)'

transpose

Given an iterable of iterables, it returns a new iterable of iterables that generates values transposed. It is a generalization of zip for a several number of iterables.

If transpose method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

transpose :: @[@[a]] ~> () -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]).transpose() /* (
    (1 4 7)
    (2 5 8)
    (3 6 9)
) */

Iterum([
    [1, 2],
    'abcd',
    [7, 8, 9]
]).transpose() /* (
    (1 'a' 7)
    (2 'b' 8)
) */

transpose :: [[a]] -> @[@[a]]

Example:

const {transpose} = require('iterum')

transpose([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]) /* (
    (1 4 7)
    (2 5 8)
    (3 6 9)
) */

transpose([
    [1, 2],
    'abcd',
    [7, 8, 9]
]) /* (
    (1 'a' 7)
    (2 'b' 8)
) */

transposeLongest

Given an iterable of iterables, it returns a new iterable of iterables that generates values transposed. However, instead of transpose, this result generates a list of iterables until the longest iterable is consumed. The holes of iterables with less values are filled with undefined value.

If transposeLongest method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

transposeLongest :: @[@[a]] ~> () -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]).transposeLongest() /* (
    (1 4 7)
    (2 5 8)
    (3 6 9)
) */

Iterum([
    [1, 2],
    'abcd',
    [7, 8, 9]
]).transposeLongest() /* (
    (1 'a' 7)
    (2 'b' 8)
    (undefined 'c')
    (undefined 'd' undefined)
) */

transposeLongest :: [[a]] -> @[@[a]]

Example:

const {transposeLongest} = require('iterum')

transposeLongest([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]) /* (
    (1 4 7)
    (2 5 8)
    (3 6 9)
) */

transposeLongest([
    [1, 2],
    'abcd',
    [7, 8, 9]
]) /* (
    (1 'a' 7)
    (2 'b' 8)
    (undefined 'c' 9)
    (undefined 'd' undefined)
) */

uniq

Given an iterable it returns a new Iterum instance that iterates over the values without duplications using sameValueZero for equality comparisons. The order of iteration values is determined by the order they occur in the given iterable.

If uniq method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

uniq :: @[a] ~> () -> @[a]

Example:

const Iterum = require('iterum')

Iterum([1, NaN, 4, '1', NaN, 3, 1, 4])
    .uniq() // (1 NaN 4 '1' 3)

uniq :: [a] -> @[a]

Example:

const {uniq} = require('iterum')

uniq([1, NaN, 4, '1', NaN, 3, 1, 4]) // (1 NaN 4 '1' 3)
uniq({foo: 'bar'}) // throwS a TypeError

uniqBy

Given an iterable and a function f, it returns a new iterable that iterates over the values without duplications using sameValueZero equality comparison over f transformation. For example, a and b values are equal if sameValueZero(f(a), f(b)) returns true. The order of iteration values is determined by the order they occur in the given iterable.

If uniqBy method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

uniqBy :: @[a] ~> (a -> b) -> @[a]

Example:

const Iterum = require('iterum')

Iterum(['abc', '2.1', '3', '2.4', 'cba'])
    .uniqBy(parseInt) // ('abc', '2.1', '3')

uniqBy :: (a -> b) -> [a] -> @[a]

Example:

const {uniqBy} = require('iterum')

uniqBy(parseInt, ['abc', '2.1', '3', '2.4', 'cba']) // ('abc', '2.1', '3')

uniqWith

Given an iterable and a binary predicate cmp, it returns a new iterable that iterates over the values without duplications using cmp for equality comparisons. The order of iteration values is determined by the order they occur in the given iterable.

If uniqWith method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

uniqWith :: @[a] ~> ((a, b) -> Boolean) -> @[a]

Example

const Iterum = require('iterum')

const cmpPairDiff = (a, b) => a[0] - a[1] === b[0] - b[1]

const iterable = Iterum([[5, 2], [2, 0], [2, 3], [-2, -1], [3, 0], [1, 4]])

iterable.uniqWith(cmpPairDiff) // ([5, 2] [2, 0] [2, 3] [1, 4])
iterable.uniqWith([5, 2]) // throw a TypeError

uniqWith :: ((a, b) -> Boolean) -> [a] -> @[a]

Example

const {uniqWith} = require('iterum')

const cmpPairDiff = (a, b) => a[0] - a[1] === b[0] - b[1]

const iterable = [[5, 2], [2, 0], [2, 3], [-2, -1], [3, 0], [1, 4]]

uniqWith(cmpPairDiff, iterable) // ([5, 2] [2, 0] [2, 3] [1, 4])
uniqWith([5, 2], iterable) // throw a TypeError
uniqWith(cmpPairDiff, 3) // throw a TypeError

variations

Given an iterable and a number n, it returns a new iterable that iterates over the variations over n or n-permutations of iterable.

If variations method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

variations :: @[a] ~> Number -> @[@[a]]

Example:

const Iterum = require('iterum')

Iterum([1, 2, 3]).variations(2) /* (
   (1 2)
   (2 1)
   (1 3)
   (3 1)
   (2 3)
   (3 2)
) */

variations :: Number -> [a] -> @[@[a]]

Example:

const {variations} = require('iterum')

variations(2, [1, 2, 3]) /* (
   (1 2)
   (2 1)
   (1 3)
   (3 1)
   (2 3)
   (3 2)
) */

zip

Given two iterables, it returns a new iterable of iterable pairs. the first value of each pair contains the values of the first iterable, and the second value of each pair contains the values of the given second iterable.

If zip method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

zip :: @[a] ~> [b] -> @[@(a, b)]

Example:

const Iterum = require('iterum')

const iterable = Iterum([3, 2, 8])

iterable.zip([4, 5, 6]) // ((3 4) (2 5) (8 6))
iterable.zip([10, 0]) // ((3 10) (2 0))
iterable.zip(5) // throws a TypeError

zip :: [a] -> [b] -> @[@(a, b)]

Example:

const {zip} = require('iterum')

const iterable = [3, 2, 8]

zip(iterable, [4, 5, 6]) // ((3 4) (2 5) (8 6))
zip(iterable, [10, 0]) // ((3 10) (2 0))
zip(5, iterable) // throws a TypeError
zip(iterable, {}) // throws a TypeError

zipLongest

This method behaves like zip. However, if first or second iterable generates less values than the other, these first or second values of these pairs are filled with undefined values, respectively.

If zipLongest method or function does not take the arguments defined by the signatures specified below, it throws a TypeError.

zipLongest :: @[a] ~> [b] -> @[@(a, b)]

Example:

const Iterum = require('iterum')

const iterable = Iterum([3, 2, 8])

iterable.zipLongest([4, 5, 6]) // ((3 4) (2 5) (8 6))
iterable.zipLongest([10, 0]) // ((3 10) (2 0) (8 undefined))
iterable.zipLongest([10, 0, 3, 2]) // ((3 10) (2 0) (8 3) (undefined 2))
iterable.zipLongest(5) // throws a TypeError

zipLongest :: [a] -> [b] -> @[@(a, b)]

Example:

const {zipLongest} = require('iterum')

const iterable = [3, 2, 8]

zipLongest(iterable, [4, 5, 6]) // ((3 4) (2 5) (8 6))
zipLongest(iterable, [10, 0]) // ((3 10) (2 0) (8 undefined))
zipLongest(iterable, [10, 0, 3, 2]) // ((3 10) (2 0) (8 3) (undefined 2))

zipLongest(5, iterable) // throws a TypeError
zipLongest(iterable, {}) // throws a TypeError