aiken/collection/list

Functions

Constructing

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]

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

Inspecting

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

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

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

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)
list.head([]) == None

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

Checks whether a list is empty.

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

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

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

Modifying

Extracting

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]

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

Drop the first n elements of a list.

list.drop([1, 2, 3], 2) == [3]
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 }) == [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]

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

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

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]

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 }) == [1]

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

Removes duplicate elements from a list.

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

Mapping

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]

for_each(self: List<a>, do: fn(a) -> Void) -> Void

Perform an action for each element of a list.

list.for_each(labels, do: fn(lbl) { trace lbl Void })

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]

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]

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

Return the list with its elements in the reserve order.

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

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]

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"])

Combining

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]

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]

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")]

Transforming

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]

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")
]

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([#[1], #[2], #[3]], #[0], bytearray.concat) == #[0, 1, 2, 3]
list.reduce([True, False, True], False, fn(b, a) { or { b, a } }) == True
Search Document