# Functions

## `all(self: List<a>, predicate: fn(a) -> Bool) -> Bool`

Determine if all elements of the list satisfy the given predicate.

Note: an empty list always satisfies the predicate.

``````list.all([], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n > 0 }) == True
list.all([1, 2, 3], fn(n) { n == 2 }) == False
``````

## `any(self: List<a>, predicate: fn(a) -> Bool) -> Bool`

Determine if at least one element of the list satisfies the given predicate.

Note: an empty list never satisfies the predicate.

``````list.any([], fn(n) { n > 2 }) == False
list.any([1, 2, 3], fn(n) { n > 0 }) == True
list.any([1, 2, 3], fn(n) { n == 2 }) == True
list.any([1, 2, 3], fn(n) { n < 0 }) == False
``````

## `at(self: List<a>, index: Int) -> Option<a>`

Return Some(item) at the index or None if the index is out of range. The index is 0-based.

``````list.at([1, 2, 3], 1) == Some(2)
list.at([1, 2, 3], 42) == None
``````

## `concat(left: List<a>, right: List<a>) -> List<a>`

Merge two lists together.

``````list.concat([], []) == []
list.concat([], [1, 2, 3]) == [1, 2, 3]
list.concat([1, 2, 3], [4, 5, 6]) == [1, 2, 3, 4, 5, 6]
``````

## `count(self: List<a>, predicate: fn(a) -> Bool) -> Int`

Count how many items in the list satisfy the given predicate.

``````list.count([], fn(a) { a > 2}) == 0
list.count([1, 2, 3], fn(a) { n > 0 }) == 3
list.count([1, 2, 3], fn(a) { n >= 2 }) == 2
list.count([1, 2, 3], fn(a) { n > 5 }) == 0
``````

## `delete(self: List<a>, elem: a) -> List<a>`

Remove the first occurrence of the given element from the list.

``````list.delete([1, 2, 3, 1], 1) == [2, 3, 1]
list.delete([1, 2, 3], 14) == [1, 2, 3]
``````

## `difference(self: List<a>, with: List<a>) -> List<a>`

Remove the first occurrence of each element of the second list from the first one.

``````list.difference(["h", "e", "l", "l", "o"], ["l", "e", "l"]) == ["h", "o"]
list.difference([1, 2, 3, 4, 5], [1, 1, 2]) == [3, 4, 5]
list.difference([1, 2, 3], []) == [1, 2, 3]
``````

## `drop(self: List<a>, n: Int) -> List<a>`

Drop the first `n` elements of a list.

``````list.drop([1, 2, 3], 2) == 
list.drop([], 42) == []
list.drop([1, 2, 3], 42) == []
``````

## `drop_while(self: List<a>, predicate: fn(a) -> Bool) -> List<a>`

Returns the suffix of the given list after removing all elements that satisfy the predicate.

``````list.drop_while([1, 2, 3], fn(x) { x < 2 }) == [2, 3]
list.drop_while([], fn(x) { x > 2 }) == []
list.drop_while([1, 2, 3], fn(x) { x == 3 }) == [1, 2, 3]
``````

## `filter(self: List<a>, predicate: fn(a) -> Bool) -> List<a>`

Produce a list of elements that satisfy a predicate.

``````list.filter([1, 2, 3], fn(x) { x >= 2 }) == [2, 3]
list.filter([], fn(x) { x > 2 }) == []
list.filter([1, 2, 3], fn(x) { x == 3 }) == 
``````

## `filter_map(self: List<a>, predicate: fn(a) -> Option<b>) -> List<b>`

Produce a list of transformed elements that satisfy a predicate.

``````let transform = fn(x) { if x % 2 == 0 { None } else { Some(3*x) } }
list.filter_map([1, 2, 3], transform) == [3, 9]
``````

## `find(self: List<a>, predicate: fn(a) -> Bool) -> Option<a>`

Find the first element satisfying the given predicate, if any.

``````list.find([1, 2, 3], fn(x) { x == 2 }) == Some(2)
list.find([4, 5, 6], fn(x) { x == 2 }) == None
``````

## `flat_map(self: List<a>, with: fn(a) -> List<b>) -> List<b>`

Map elements of a list into a new list and flatten the result.

``````list.flat_map([1, 2, 3], fn(a) { [a, 2*a] }) == [1, 2, 2, 4, 3, 6]
``````

## `foldl(self: List<a>, zero: b, with: fn(a, b) -> b) -> b`

Reduce a list from left to right.

``````list.foldl([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldl([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [3, 2, 1]
``````

## `foldr(self: List<a>, zero: b, with: fn(a, b) -> b) -> b`

Reduce a list from right to left.

``````list.foldr([1, 2, 3], 0, fn(n, total) { n + total }) == 6
list.foldr([1, 2, 3], [], fn(x, xs) { [x, ..xs] }) == [1, 2, 3]
``````

## `has(self: List<a>, elem: a) -> Bool`

Figures out whether a list contain the given element.

``````list.has([1, 2, 3], 2) == True
list.has([1, 2, 3], 14) == False
list.has([], 14) == False
``````

Get the first element of a list

``````list.head([1, 2, 3]) == Some(1)
``````

## `index_of(self: List<a>, elem: a) -> Option<Int>`

Gets the index of an element of a list, if any. Otherwise, returns None.

``````list.index_of([1, 5, 2], 2) == Some(2)
list.index_of([1, 7, 3], 4) == None
list.index_of([1, 0, 9, 6], 6) == 3
list.index_of([], 6) == None
``````

## ```indexed_foldr( self: List<a>, zero: result, with: fn(Int, a, result) -> result, ) -> result```

Like `foldr`, but also provides the position (0-based) of the elements when iterating.

``````let group = fn(i, x, xs) { [(i, x), ..xs] }
list.indexed_foldr(["a", "b", "c"], [], group) == [
(0, "a"),
(1, "b"),
(2, "c")
]
``````

## `indexed_map(self: List<a>, with: fn(Int, a) -> result) -> List<result>`

List `map` but provides the position (0-based) of the elements while iterating.

``````list.indexed_map([1, 2, 3], fn(i, x) { i + x }) == [1, 3, 5]
``````

## `init(self: List<a>) -> Option<List<a>>`

Return all elements except the last one.

``````list.init([]) == None
list.init([1, 2, 3]) == Some([1, 2])
``````

## `is_empty(self: List<a>) -> Bool`

Checks whether a list is empty.

``````list.is_empty([]) == True
list.is_empty([1, 2, 3]) == False
``````

## `last(self: List<a>) -> Option<a>`

Get the last in the given list, if any.

``````list.last([]) == None
list.last([1, 2, 3]) == Some(3)
``````

## `length(self: List<a>) -> Int`

Get the number of elements in the given list.

``````list.length([]) == 0
list.length([1, 2, 3]) == 3
``````

## `map(self: List<a>, with: fn(a) -> result) -> List<result>`

Apply a function to each element of a list.

``````list.map([1, 2, 3, 4], fn(n) { n + 1 }) == [2, 3, 4, 5]
``````

## `map2(self: List<a>, bs: List<b>, with: fn(a, b) -> result) -> List<result>`

Apply a function of two arguments, combining elements from two lists.

Note: if one list is longer, the extra elements are dropped.

``````list.map2([1, 2, 3], [1, 2], fn(a, b) { a + b }) == [2, 4]
``````

## ```map3( self: List<a>, bs: List<b>, cs: List<c>, with: fn(a, b, c) -> result, ) -> List<result>```

Apply a function of three arguments, combining elements from three lists.

Note: if one list is longer, the extra elements are dropped.

``````list.map3([1, 2, 3], [1, 2], [1, 2, 3], fn(a, b, c) { a + b + c }) == [3, 6]
``````

## `partition(self: List<a>, predicate: fn(a) -> Bool) -> (List<a>, List<a>)`

Returns a tuple with all elements that satisfy the predicate at first element, and the rest as second element.

``````list.partition([1, 2, 3, 4], fn(x) { x % 2 == 0 }) == ([2, 4], [1, 3])
``````

## `push(self: List<a>, elem: a) -> List<a>`

Add an element in front of the list. Sometimes useful when combined with other functions.

``````list.push([2, 3], 1) == [1, ..[2, 3]] == [1, 2, 3]
``````

## `range(from: Int, to: Int) -> List<Int>`

Construct a list of a integer from a given range.

``````list.range(0, 3) == [0, 1, 2, 3]
list.range(-1, 1) == [-1, 0, 1]
``````

## `reduce(self: List<a>, zero: b, with: fn(b, a) -> b) -> b`

Reduce a list from left to right using the accumulator as left operand. Said differently, this is `foldl` with callback arguments swapped.

``````list.reduce([#, #, #], #, bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True
``````

## `repeat(elem: a, n_times: Int) -> List<a>`

Construct a list filled with n copies of a value.

``````list.repeat("na", 3) == ["na", "na", "na"]
``````

## `reverse(self: List<a>) -> List<a>`

Return the list with its elements in the reserve order.

``````list.reverse([1, 2, 3]) == [3, 2, 1]
``````

## `slice(self: List<a>, from: Int, to: Int) -> List<a>`

Extract a sublist from the given list using 0-based indexes. Negative indexes wrap over, so `-1` refers to the last element of the list.

``````list.slice([1, 2, 3, 4, 5, 6], from: 2, to: 4) == [3, 4, 5]
list.slice([1, 2, 3, 4, 5, 6], from: -2, to: -1) == [5, 6]
list.slice([1, 2, 3, 4, 5, 6], from: 1, to: -1) == [2, 3, 4, 5, 6]
``````

## `sort(self: List<a>, compare: fn(a, a) -> Ordering) -> List<a>`

Sort a list in ascending order using the given comparison function.

``````use aiken/int

sort([3, 1, 4, 0, 2], int.compare) == [0, 1, 2, 3, 4]
sort([1, 2, 3], int.compare) == [1, 2, 3]
``````

## `span(self: List<a>, n: Int) -> (List<a>, List<a>)`

Cut a list in two, such that the first list contains the given number of / elements and the second list contains the rest.

Fundamentally equivalent to (but more efficient):

``````// span(xs, n) == (take(xs, n), drop(xs, n))
span([1, 2, 3, 4, 5], 3) == ([1, 2, 3], [4, 5])
``````

## `tail(self: List<a>) -> Option<List<a>>`

Get elements of a list after the first one, if any.

``````list.tail([]) == None
list.tail([1, 2, 3]) == Some([2, 3])
``````

## `take(self: List<a>, n: Int) -> List<a>`

Get the first `n` elements of a list.

``````list.take([1, 2, 3], 2) == [1, 2]
list.take([1, 2, 3], 14) == [1, 2, 3]
``````

## `take_while(self: List<a>, predicate: fn(a) -> Bool) -> List<a>`

Returns the longest prefix of the given list where all elements satisfy the predicate.

``````list.take_while([1, 2, 3], fn(x) { x > 2 }) == []
list.take_while([1, 2, 3], fn(x) { x < 2 }) == 
``````

## `unique(self: List<a>) -> List<a>`

Removes duplicate elements from a list.

``````list.unique([1, 2, 3, 1]) == [1, 2, 3]
``````

## `unzip(self: List<(a, b)>) -> (List<a>, List<b>)`

Decompose a list of tuples into a tuple of lists.

``````list.unzip([(1, "a"), (2, "b")]) == ([1, 2], ["a", "b"])
``````

## `zip(self: List<a>, bs: List<b>) -> List<(a, b)>`

Combine two lists together.

Note: if one list is longer, the extra elements are dropped.

``````list.zip([1, 2], ["a", "b", "c"]) == [(1, "a"), (2, "b")]
``````