aiken/collection/list

Types

Alias

Fold2<a, b, result> = fn(a, b) -> result

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]

foldl2(
  self: List<elem>,
  zero_a: a,
  zero_b: b,
  with: fn(elem, a, b, Fold2<a, b, result>) -> result,
  return: Fold2<a, b, result>,
) -> result

This function was released by mistake as part of the v2 series of updates. However, unlike the name suggests, it isn’t a left-fold but a right-fold.

It cannot be removed without changing its semantic and possibly breaking existing code that relies on it. Sorry for the inconvenience.

Be also aware that starting from v3.0.0, this has been fixed. So be careful if you’ve been using foldl2 when upgrading to v3.0.0; you very likely want to use v3’s foldr2 instead.

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