gleam/list

Lists are an ordered sequence of elements and are one of the most common data types in Gleam.

New elements can be added and removed from the front of a list in constant time, while adding and removing from the end requires traversing the copying the whole list, so keep this in mind when designing your programs.

There is a dedicated syntax for prefixing to a list:

let new_list = [1, 2, ..existing_list]

And a matching syntax for getting the first elements of a list:

case list {
  [first_element, ..rest] -> first_element
  _ -> "this pattern matches when the list is empty"
}

Types

pub type ContinueOrStop(a) {
  Continue(a)
  Stop(a)
}

Constructors

  • Continue(a)
  • Stop(a)

An error value returned by the strict_zip function.

pub type LengthMismatch {
  LengthMismatch
}

Constructors

  • LengthMismatch

Functions

pub fn all(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool

Returns True if the given function returns True for all the elements in the given list. If the function returns False for any of the elements it immediately returns False without checking the rest of the list.

Examples

> all([], fn(x) { x > 3 })
True

> all([4, 5], fn(x) { x > 3 })
True

> all([4, 3], fn(x) { x > 3 })
False
pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool

Returns True if the given function returns True for any the elements in the given list. If the function returns True for any of the elements it immediately returns True without checking the rest of the list.

Examples

> any([], fn(x) { x > 3 })
False

> any([4, 5], fn(x) { x > 3 })
True

> any([4, 3], fn(x) { x > 4 })
False

> any([3, 4], fn(x) { x > 3 })
True
pub fn append(first: List(a), second: List(a)) -> List(a)

Joins one list onto the end of another.

This function runs in linear time, and it traverses and copies the first list.

Examples

> append([1, 2], [3])
[1, 2, 3]
pub fn at(in list: List(a), get index: Int) -> Result(a, Nil)

Returns the element in the Nth position in the list, with 0 being the first position.

Error(Nil) is returned if the list is not long enough for the given index.

For any index less than 0 this function behaves as if it was set to 0.

Examples

> at([1, 2, 3], 1)
Ok(2)

> at([1, 2, 3], 5)
Error(Nil)
pub fn chunk(in list: List(a), by f: fn(a) -> b) -> List(List(a))

Returns a list of chunks in which the result of calling f on each element is the same.

Examples

> [1, 2, 2, 3, 4, 4, 6, 7, 7] |> chunk(by: fn(n) { n % 2 })
[[1], [2, 2], [3], [4, 4, 6], [7, 7]]
pub fn combination_pairs(items: List(a)) -> List(#(a, a))

Return unique pair combinations of elements in the list

Examples

> combination_pairs([1, 2, 3])
[#(1, 2), #(1, 3), #(2, 3)]
pub fn combinations(items: List(a), by n: Int) -> List(List(a))

Return unique combinations of elements in the list.

Examples

> combinations([1, 2, 3], 2)
[[1, 2], [1, 3], [2, 3]]

 > combinations([1, 2, 3, 4], 3)
 [[1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
pub fn contains(list: List(a), any elem: a) -> Bool

Determines whether or not a given element exists within a given list.

This function traverses the list to find the element, so it runs in linear time.

Examples

> [] |> contains(any: 0)
False

> [0] |> contains(any: 0)
True

> [1] |> contains(any: 0)
False

> [1, 1] |> contains(any: 0)
False

> [1, 0] |> contains(any: 0)
True
pub fn drop(from list: List(a), up_to n: Int) -> List(a)

Returns a list that is the given list with up to the given number of elements removed from the front of the list.

If the element has less than the number of elements an empty list is returned.

This function runs in linear time but does not copy the list.

Examples

> drop([1, 2, 3, 4], 2)
[3, 4]

> drop([1, 2, 3, 4], 9)
[]
pub fn drop_while(in list: List(a), satisfying predicate: fn(a) ->
    Bool) -> List(a)

Drops the first elements in a given list for which the predicate funtion returns True.

Examples

> drop_while([1, 2, 3, 4], fn (x) { x < 3 })
[3, 4]
pub fn each(list: List(a), f: fn(a) -> b) -> Nil

Calls a function for each element in a list, discarding the results.

pub fn filter(list: List(a), for predicate: fn(a) -> Bool) -> List(
  a,
)

Returns a new list containing only the elements from the first list for which the given functions returns True.

Examples

> filter([2, 4, 6, 1], fn(x) { x > 2 })
[4, 6]

> filter([2, 4, 6, 1], fn(x) { x > 6 })
[]
pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, c)) -> List(
  b,
)

Returns a new list containing only the elements from the first list for which the given functions returns Ok(_).

Examples

> filter_map([2, 4, 6, 1], Error)
[]

> filter_map([2, 4, 6, 1], fn(x) { Ok(x + 1) })
[3, 5, 7, 2]
pub fn find(in haystack: List(a), one_that is_desired: fn(a) ->
    Bool) -> Result(a, Nil)

Finds the first element in a given list for which the given function returns True.

Returns Error(Nil) if no such element is found.

Examples

> find([1, 2, 3], fn(x) { x > 2 })
Ok(3)

> find([1, 2, 3], fn(x) { x > 4 })
Error(Nil)

> find([], fn(_) { True })
Error(Nil)
pub fn find_map(in haystack: List(a), with fun: fn(a) ->
    Result(b, c)) -> Result(b, Nil)

Finds the first element in a given list for which the given function returns Ok(new_value), then returns the wrapped new_value.

Returns Error(Nil) if no such element is found.

Examples

> find_map([[], [2], [3]], head)
Ok(2)

> find_map([[], []], head)
Error(Nil)

> find_map([], head)
Error(Nil)
pub fn first(list: List(a)) -> Result(a, Nil)

Gets the first element from the start of the list, if there is one.

Examples

> first([])
Error(Nil)

> first([0])
Ok(0)

> first([1, 2])
Ok(1)
pub fn flat_map(over list: List(a), with fun: fn(a) -> List(b)) -> List(
  b,
)

Maps the list with the given function and then flattens the result.

Examples

> flat_map([2, 4, 6], fn(x) { [x, x + 1] })
[2, 3, 4, 5, 6, 7]
pub fn flatten(lists: List(List(a))) -> List(a)

Flattens a list of lists into a single list.

This function runs in linear time, and it traverses and copies all the inner lists.

Examples

> flatten([[1], [2, 3], []])
[1, 2, 3]
pub fn fold(over list: List(a), from initial: b, with fun: fn(
    b,
    a,
  ) -> b) -> b

Reduces a list of elements into a single value by calling a given function on each element, going from left to right.

fold([1, 2, 3], 0, add) is the equivalent of add(add(add(0, 1), 2), 3).

This function runs in linear time.

pub fn fold_right(over list: List(a), from initial: b, with fun: fn(
    b,
    a,
  ) -> b) -> b

Reduces a list of elements into a single value by calling a given function on each element, going from right to left.

fold_right([1, 2, 3], 0, add) is the equivalent of add(add(add(0, 3), 2), 1).

This function runs in linear time.

Unlike fold this function is not tail recursive. Where possible use fold instead as it will use less memory.

pub fn fold_until(over collection: List(a), from accumulator: b, with fun: fn(
    b,
    a,
  ) -> ContinueOrStop(b)) -> b

A variant of fold that allows to stop folding earlier.

The folding function should return ContinueOrStop(accumulator). If the returned value is Continue(accumulator) fold_until will try the next value in the list. If the returned value is Stop(accumulator) fold_until will stop and return that accumulator.

Examples

[1, 2, 3, 4]
|> fold_until(0, fn(acc, i) {
  case i < 3 {
    True -> Continue(acc + i)
    False -> Stop(acc)
  }
})
pub fn index_fold(over over: List(a), from initial: b, with fun: fn(
    b,
    a,
    Int,
  ) -> b) -> b

Like fold but the folding function also receives the index of the current element.

Examples

["a", "b", "c"]
|> list.index_fold([], fn(acc, item, index) { ... })
pub fn index_map(list: List(a), with fun: fn(Int, a) -> b) -> List(
  b,
)

Returns a new list containing only the elements of the first list after the function has been applied to each one and their index.

The index starts at 0, so the first element is 0, the second is 1, and so on.

Examples

> index_map(["a", "b"], fn(i, x) { #(i, x) })
[#(0, "a"), #(1, "b")]
pub fn interleave(list: List(List(a))) -> List(a)

Make a list alternating the elements from the given lists

Examples

> list.interleave([[1, 2], [101, 102], [201, 202]])
[1, 101, 201, 2, 102, 202]
pub fn intersperse(list: List(a), with elem: a) -> List(a)

Inserts a given value between each existing element in a given list.

This function runs in linear time and copies the list.

Examples

> intersperse([1, 1, 1], 2)
[1, 2, 1, 2, 1]

> intersperse([], 2)
[]
pub fn is_empty(list: List(a)) -> Bool

Determines whether or not the list is empty.

This function runs in constant time.

Examples

> is_empty([])
True

> is_empty([1])
False

> is_empty([1, 1])
False
pub fn key_find(in keyword_list: List(#(a, b)), find desired_key: a) -> Result(
  b,
  Nil,
)

Given a list of 2-element tuples, finds the first tuple that has a given key as the first element and returns the second element.

If no tuple is found with the given key then Error(Nil) is returned.

This function may be useful for interacting with Erlang code where lists of tuples are common.

Examples

> key_find([#("a", 0), #("b", 1)], "a")
Ok(0)

> key_find([#("a", 0), #("b", 1)], "b")
Ok(1)

> key_find([#("a", 0), #("b", 1)], "c")
Error(Nil)
pub fn key_pop(haystack: List(#(a, b)), key: a) -> Result(
  #(b, List(#(a, b))),
  Nil,
)

Given a list of 2-element tuples, finds the first tuple that has a given key as the first element. This function will return the second element of the found tuple and list with tuple removed.

If no tuple is found with the given key then Error(Nil) is returned.

Examples

> key_pop([#("a", 0), #("b", 1)], "a")
Ok(#(0, [#("b", 1)]))

> key_pop([#("a", 0), #("b", 1)], "b")
Ok(#(1, [#("a", 0)]))

> key_pop([#("a", 0), #("b", 1)], "c")
Error(Nil)
pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(
  #(a, b),
)

Given a list of 2-element tuples, inserts a key and value into the list.

If there was already a tuple with the key then it is replaced, otherwise it is added to the end of the list.

Examples

> key_set([#(5, 0), #(4, 1)], 4, 100)
[#(5, 0), #(4, 100)]

> key_set([#(5, 0), #(4, 1)], 1, 100)
[#(5, 0), #(4, 1), #(1, 100)]
pub fn last(list: List(a)) -> Result(a, Nil)

Returns the last element in the given list.

Returns Error(Nil) if the list is empty.

This function runs in linear time. For a collection oriented around performant access at either end, see gleam/queue.Queue.

Examples

> last([])
Error(Nil)

> last([1, 2, 3, 4, 5])
Ok(5)
pub fn length(of list: List(a)) -> Int

Counts the number of elements in a given list.

This function has to traverse the list to determine the number of elements, so it runs in linear time.

This function is natively implemented by the virtual machine and is highly optimised.

Examples

> length([])
0

> length([1])
1

> length([1, 2])
2
pub fn map(list: List(a), with fun: fn(a) -> b) -> List(b)

Returns a new list containing only the elements of the first list after the function has been applied to each one.

Examples

> map([2, 4, 6], fn(x) { x * 2 })
[4, 8, 12]
pub fn map_fold(over list: List(a), from acc: b, with fun: fn(
    b,
    a,
  ) -> #(b, c)) -> #(b, List(c))

Similar to map but also lets you pass around an accumulated value.

Examples

> map_fold(
    over: [1, 2, 3],
    from: 100,
    with: fn(memo, i) { #(i * 2, memo + i) }
 )
 #([2, 4, 6], 106)
pub fn new() -> List(a)

Returns a new empty list.

Examples

> new()
[]
pub fn partition(list: List(a), with categorise: fn(a) -> Bool) -> #(
  List(a),
  List(a),
)
pub fn permutations(l: List(a)) -> List(List(a))

Returns all the permutations of a list. All values must be unique.

Examples

> permutations([1, 2])
[[1, 2], [2, 1]]
pub fn pop(in haystack: List(a), one_that is_desired: fn(a) ->
    Bool) -> Result(#(a, List(a)), Nil)

Removes the first element in a given list for which the predicate funtion returns True.

Returns Error(Nil) if no such element is found.

Examples

> pop([1, 2, 3], fn(x) { x > 2 })
Ok(#(3, [1, 2]))

> pop([1, 2, 3], fn(x) { x > 4 })
Error(Nil)

> pop([], fn(_) { True })
Error(Nil)
pub fn pop_map(in haystack: List(a), one_that is_desired: fn(a) ->
    Result(b, c)) -> Result(#(b, List(a)), Nil)

Removes the first element in a given list for which the given function returns Ok(new_value), then returns the wrapped new_value as well as list with the value removed.

Returns Error(Nil) if no such element is found.

Examples

> pop_map([[], [2], [3]], head)
Ok(#(2, [[], [3]]))

> pop_map([[], []], head)
Error(Nil)

> pop_map([], head)
Error(Nil)
pub fn range(from start: Int, to stop: Int) -> List(Int)

Creates a list of ints ranging from a given start and finish.

Examples

> range(0, 0)
[]

> range(0, 5)
[0, 1, 2, 3, 4]

> range(1, -5)
[1, 0, -1, -2, -3, -4]
pub fn reduce(over list: List(a), with fun: fn(a, a) -> a) -> Result(
  a,
  Nil,
)

This function acts similar to fold, but does not take an initial state. Instead, it starts from the first element in the list and combines it with each subsequent element in turn using the given function. The function is called as fun(accumulator, current_element).

Returns Ok to indicate a successful run, and Error if called on an empty list.

Examples

> [] |> reduce(fn(acc, x) { acc + x })
Error(Nil)

> [1, 2, 3, 4, 5] |> reduce(fn(acc, x) { acc + x })
Ok(15)
pub fn repeat(item a: a, times times: Int) -> List(a)

Builds a list of a given value a given number of times.

Examples

> repeat("a", times: 0)
[]

> repeat("a", times: 5)
["a", "a", "a", "a", "a"]
pub fn rest(list: List(a)) -> Result(List(a), Nil)

Returns the list minus the first element. If the list is empty, Error(Nil) is returned.

This function runs in constant time and does not make a copy of the list.

Examples

> rest([])
Error(Nil)

> rest([0])
Ok([])

> rest([1, 2])
Ok([2])
pub fn reverse(xs: List(a)) -> List(a)

Creates a new list from a given list containing the same elements but in the opposite order.

This function has to traverse the list to create the new reversed list, so it runs in linear time.

This function is natively implemented by the virtual machine and is highly optimised.

Examples

> reverse([])
[]

> reverse([1])
[1]

> reverse([1, 2])
[2, 1]
pub fn scan(over list: List(a), from initial: b, with fun: fn(
    b,
    a,
  ) -> b) -> List(b)

Similar to fold, but yields the state of the accumulator at each stage.

Examples

> scan(over: [1, 2, 3], from: 100, with: fn(acc, i) { acc + i })
[101, 103, 106]
pub fn sized_chunk(in list: List(a), into count: Int) -> List(
  List(a),
)

Returns a list of chunks containing count elements each.

If the last chunk does not have count elements, it is instead a partial chunk, with less than count elements.

For any count less than 1 this function behaves as if it was set to 1.

Examples

> [1, 2, 3, 4, 5, 6] |> sized_chunk(into: 2)
[[1, 2], [3, 4], [5, 6]]

> [1, 2, 3, 4, 5, 6, 7, 8] |> sized_chunk(into: 3)
[[1, 2, 3], [4, 5, 6], [7, 8]]
pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(
  a,
)

Sorts from smallest to largest based upon the ordering specified by a given function.

Examples

> import gleam/int
> list.sort([4, 3, 6, 5, 4, 1, 2], by: int.compare)
[1, 2, 3, 4, 4, 5, 6]
pub fn split(list list: List(a), at index: Int) -> #(
  List(a),
  List(a),
)

Splits a list in two before the given index.

If the list is not long enough to have the given index the before list will be the input list, and the after list will be empty.

Examples

> split([6, 7, 8, 9], 0)
#([], [6, 7, 8, 9])

> split([6, 7, 8, 9], 2)
#([6, 7], [8, 9])

> split([6, 7, 8, 9], 4)
#([6, 7, 8, 9], [])
pub fn split_while(list list: List(a), satisfying predicate: fn(a) ->
    Bool) -> #(List(a), List(a))

Splits a list in two before the first element that a given function returns False for.

If the function returns True for all elements the first list will be the input list, and the second list will be empty.

Examples

> split_while([1, 2, 3, 4, 5], fn(x) { x <= 3 })
#([1, 2, 3], [4, 5])

> split_while([1, 2, 3, 4, 5], fn(x) { x <= 5 })
#([1, 2, 3, 4, 5], [])
pub fn strict_zip(l1: List(a), l2: List(b)) -> Result(
  List(#(a, b)),
  LengthMismatch,
)

Takes two lists and returns a single list of 2-element tuples.

If one of the lists is longer than the other, an Error is returned.

Examples

> strict_zip([], [])
Ok([])

> strict_zip([1, 2], [3])
Error(LengthMismatch)

> strict_zip([1], [3, 4])
Error(LengthMismatch)

> strict_zip([1, 2], [3, 4])
Ok([#(1, 3), #(2, 4)])
pub fn take(from list: List(a), up_to n: Int) -> List(a)

Returns a list containing the first given number of elements from the given list.

If the element has less than the number of elements then the full list is returned.

This function runs in linear time but does not copy the list.

Examples

> take([1, 2, 3, 4], 2)
[1, 2]

> take([1, 2, 3, 4], 9)
[1, 2, 3, 4]
pub fn take_while(in list: List(a), satisfying predicate: fn(a) ->
    Bool) -> List(a)

Takes the first elements in a given list for which the predicate funtion returns True.

Examples

> take_while([1, 2, 3, 2, 4], fn (x) { x < 3 })
[1, 2]
pub fn transpose(list_of_list: List(List(a))) -> List(List(a))

Transpose rows and columns of the list of lists.

Examples

> transpose([[1, 2, 3], [101, 102, 103]])
[[1, 101], [2, 102], [3, 103]]
pub fn try_fold(over collection: List(a), from accumulator: b, with fun: fn(
    b,
    a,
  ) -> Result(b, c)) -> Result(b, c)

A variant of fold that might fail.

The folding function should return Result(accumulator, error). If the returned value is Ok(accumulator) try_fold will try the next value in the list. If the returned value is Error(error) try_fold will stop and return that error.

Examples

[1, 2, 3, 4]
|> try_fold(0, fn(acc, i) {
  case i < 3 {
    True -> Ok(acc + i)
    False -> Error(Nil)
  }
})
pub fn try_map(over list: List(a), with fun: fn(a) ->
    Result(b, c)) -> Result(List(b), c)

Takes a function that returns a Result and applies it to each element in a given list in turn.

If the function returns Ok(new_value) for all elements in the list then a list of the new values is returned.

If the function returns Error(reason) for any of the elements then it is returned immediately. None of the elements in the list are processed after one returns an Error.

Examples

> try_map([1, 2, 3], fn(x) { Ok(x + 2) })
Ok([3, 4, 5])

> try_map([1, 2, 3], fn(_) { Error(0) })
Error(0)

> try_map([[1], [2, 3]], head)
Ok([1, 2])

> try_map([[1], [], [2]], head)
Error(Nil)
pub fn unique(list: List(a)) -> List(a)

Removes any duplicate elements from a given list.

This function returns in loglinear time.

Examples

> unique([1, 1, 1, 4, 7, 3, 3, 4])
[1, 4, 7, 3]
pub fn unzip(input: List(#(a, b))) -> #(List(a), List(b))

Takes a single list of 2-element tuples and returns two lists.

Examples

> unzip([#(1, 2), #(3, 4)])
#([1, 3], [2, 4])

> unzip([])
#([], [])
pub fn window(l: List(a), by n: Int) -> List(List(a))

Returns a list of sliding windows.

Examples

> window([1,2,3,4,5], 3)
[[1, 2, 3], [2, 3, 4], [3, 4, 5]]

> window([1, 2], 4)
[]
pub fn window_by_2(l: List(a)) -> List(#(a, a))

Returns a list of tuples containing two contiguous elements.

Examples

> window_by_2([1,2,3,4])
[#(1, 2), #(2, 3), #(3, 4)]

> window_by_2([1])
[]
pub fn zip(xs: List(a), ys: List(b)) -> List(#(a, b))

Takes two lists and returns a single list of 2-element tuples.

If one of the lists is longer than the other, the remaining elements from the longer list are not used.

Examples

> zip([], [])
[]

> zip([1, 2], [3])
[#(1, 3)]

> zip([1], [3, 4])
[#(1, 3)]

> zip([1, 2], [3, 4])
[#(1, 3), #(2, 4)]