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
or if the index is less than 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 return value 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 return value.
Useful for calling a side effect for every item of a list.
> list.each([1, 2, 3], io.println)
Nil
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 it.
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 traverses all elements twice.
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 group(list: List(a), by key: fn(a) -> b) -> Map(b, List(a))
Takes a list and groups the values by a key which is built from a key function.
Does not preserve the initial value order.
Examples
> [Ok(3), Error("Wrong"), Ok(200), Ok(73)]
|> group(by: fn(i) {
case i {
Ok(_) -> "Successful"
Error(_) -> "Failed"
}
})
|> map.to_list
[
#("Failed", [Error("Wrong")]),
#("Successful", [Ok(73), Ok(200), Ok(3)])
]
> group(from: [1,2,3,4,5], with: fn(i) {fn(i) { i - i / 3 * 3 }})
|> map.to_list
[#(0, [3]), #(1, [4, 1]), #(2, [5, 2])]
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"]
|> 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) { #(memo + i, i * 2) }
)
#(106, [2, 4, 6])
pub fn partition(list: List(a), with categorise: fn(a) -> Bool) -> #(
List(a),
List(a),
)
Partitions a list into a tuple/pair of lists by a given categorisation function.
Examples
> [1, 2, 3, 4, 5] |> list.partition(int.is_odd)
#([1, 3, 5], [2, 4])
pub fn permutations(l: List(a)) -> List(List(a))
Returns all the permutations of a list.
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 prepend(to list: List(a), this item: a) -> List(a)
Prefixes an item to a list. This can also be done using the dedicated syntax instead
let new_list = [1, ..existing_list]
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)
[0]
> range(0, 5)
[0, 1, 2, 3, 4, 5]
> range(1, -5)
[1, 0, -1, -2, -3, -4, -5]
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 shuffle(list: List(a)) -> List(a)
Takes a list, randomly sorts all items and returns the shuffled list.
This function uses Erlang’s :rand
module or Javascript’s
Math.random()
to calcuate the index shuffling.
Example
list.range(1, 10)
|> list.shuffle()
> [1, 6, 9, 10, 3, 8, 4, 2, 7, 5]
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.
Notice: This function is not tail recursive, and thus may exceed stack size if called, with large lists (on target JavaScript).
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)]