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

LengthMismatch

An error value returned by the strict_zip function.

pub type LengthMismatch {
  LengthMismatch
}

Constructors

  • LengthMismatch

List

pub type List(elements) =
  List(elements)

Functions

all

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

any

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 })
False

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

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

append

pub external fn append(List(a), List(a)) -> List(a)

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

at

pub fn at(in list: List(a), get index: Int) -> Result(a, Nil)

Return 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.

Examples

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

> at([1, 2, 3], 5)
Error(Nil)

contains

pub fn contains(list: List(a), any elem: a) -> Bool

Determine 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)
True

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

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

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

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

drop

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

filter

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

filter_map

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 True.

Examples

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

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

find

pub fn find(
  in haystack: List(a),
  one_that is_desired: fn(a) -> Bool,
) -> Result(a, Nil)

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

Returns Error(Nil) if no the function does not return True for any of the elements.

Examples

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

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

> find([], fn(x) { True })
Error(Nil)

find_map

pub fn find_map(
  in haystack: List(a),
  with fun: fn(a) -> Result(b, Nil),
) -> Result(b, Nil)

Find the first element in a given list for which the given function returns Ok(new_value) and return the new value for that element.

Returns Error(Nil) if no the function does not return Ok for any of the elements.

Examples

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

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

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

flatten

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]

fold

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

Reduce 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(3, add(2, add(1, 0))).

This function runs in linear time.

fold_right

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

Reduce 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(1, add(2, add(3, 0))).

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 head(list: List(a)) -> Result(a, Nil)

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

Examples

> head([])
Error(Nil)

> head([0])
Ok(0)

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

index_map

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) { tuple(i, x) })
[tuple(0, "a"), tuple(1, "b")]

intersperse

pub fn intersperse(list: List(a), with elem: a) -> List(a)

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

is_empty

pub fn is_empty(list: List(a)) -> Bool

Determine 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

key_find

pub fn key_find(
  in keyword_list: List(tuple(a, b)),
  find desired_key: a,
) -> Result(b, Nil)

Given a list of 2 element tuples, find the first tuple that has a given key as the first element and return 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([tuple("a", 0), tuple("b", 1)], "a")
Ok(0)

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

> key_find([tuple("a", 0), tuple("b", 1)], "c")
Error(Nil)

length

pub external fn length(of: List(a)) -> Int

Count 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

map

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]

new

pub fn new() -> List(a)

Returns a new empty list.

Examples

> new()
[]

range

pub fn range(from start: Int, to stop: Int) -> List(Int)

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

repeat

pub fn repeat(item a: a, times times: Int) -> List(a)

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

reverse

pub external fn reverse(List(a)) -> List(a)

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

sort

pub fn sort(
  list: List(a),
  by compare: fn(a, a) -> Order,
) -> List(a)

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

split

pub fn split(
  list list: List(a),
  at index: Int,
) -> tuple(List(a), List(a))

Split 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)
tuple([], [6, 7, 8, 9])

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

> split([6, 7, 8, 9], 4)
tuple([6, 7, 8, 9], [])

split_while

pub fn split_while(
  list list: List(a),
  while predicate: fn(a) -> Bool,
) -> tuple(List(a), List(a))

Split 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 })
tuple([1, 2, 3], [4, 5])

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

strict_zip

pub fn strict_zip(
  l1: List(a),
  l2: List(b),
) -> Result(List(tuple(a, b)), LengthMismatch)

Takes two lists and returns a single list of 2 item 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([tuple(1, 3), tuple(2, 4)])

tail

pub fn tail(list: List(a)) -> Result(List(a), Nil)

Get 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

> tail([])
Error(Nil)

> tail([0])
Ok([])

> tail([1, 2])
Ok([2])

take

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]

traverse

pub fn traverse(
  list: List(a),
  with fun: fn(a) -> Result(b, c),
) -> Result(List(b), c)

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

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

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

> traverse([1, 2, 3], fn(x) { Error(0) })
Error(0)

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

> traverse([[1], [], [2]], head)
Error(Nil)

unique

pub fn unique(list: List(a)) -> List(a)

Remove any duplicate elements from a given list.

This function returns in log-linear time (n log n).

Examples

> unique([1, 1, 1, 4, 7, 3, 3, 4])
[1, 4, 7, 3]

zip

pub fn zip(xs: List(a), ys: List(b)) -> List(tuple(a, b))

Takes two lists and returns a single list of 2 item 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])
[tuple(1, 3)]

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

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