Packages
gleam_stdlib
0.2.0
1.0.3
1.0.2
1.0.1
1.0.0
0.71.0
0.70.0
0.69.0
0.68.1
0.68.0
0.67.1
0.67.0
0.65.0
0.64.0
0.63.2
0.63.1
0.63.0
0.62.1
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.1
0.35.0
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.2
0.30.1
0.30.0
0.29.2
0.29.1
0.29.0
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.0
0.22.3
0.22.2
0.22.1
0.22.0
0.21.0
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.18.0-rc1
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.4.0-rc1
0.3.1
0.3.0
0.2.0
retired
A standard library for the Gleam programming language
Retired package: Release invalid - Does not compile correctly
Current section
Files
Jump to
Current section
Files
src/list.gleam
import int
import order
pub enum Empty =
| Empty
pub enum NotFound =
| NotFound
pub enum LengthMismatch =
| LengthMismatch
// Using the Erlang C BIF implementation.
//
pub external fn length(List(a)) -> Int = "erlang" "length"
// Using the Erlang C BIF implementation.
//
pub external fn reverse(List(a)) -> List(a) = "lists" "reverse"
pub fn is_empty(list) {
list == []
}
pub fn contains(list, elem) {
case list {
| [] -> False
| [head | rest] -> head == elem || contains(rest, elem)
}
}
pub fn head(list) {
case list {
| [] -> Error(Empty)
| [x | _] -> Ok(x)
}
}
pub fn tail(list) {
case list {
| [] -> Error(Empty)
| [_ | xs] -> Ok(xs)
}
}
fn do_filter(list, fun, acc) {
case list {
| [] -> reverse(acc)
| [x | xs] ->
let new_acc =
case fun(x) {
| True -> [x | acc]
| False -> acc
}
do_filter(xs, fun, new_acc)
}
}
pub fn filter(list, fun) {
do_filter(list, fun, [])
}
fn do_map(list, fun, acc) {
case list {
| [] -> reverse(acc)
| [x | xs] -> do_map(xs, fun, [fun(x) | acc])
}
}
pub fn map(list, fun) {
do_map(list, fun, [])
}
fn do_index_map(list, fun, index, acc) {
case list {
| [] -> reverse(acc)
| [x | xs] -> do_index_map(xs, fun, index + 1, [fun(index, x) | acc])
}
}
pub fn index_map(list, fun) {
do_index_map(list, fun, 0, [])
}
fn do_traverse(list, fun, acc) {
case list {
| [] -> Ok(reverse(acc))
| [x | xs] ->
case fun(x) {
| Ok(y) -> do_traverse(xs, fun, [y | acc])
| Error(error) -> Error(error)
}
}
}
pub fn traverse(list, fun) {
do_traverse(list, fun, [])
}
pub fn drop(list, n) {
case n <= 0 {
| True -> list
| False ->
case list {
| [] -> []
| [_ | xs] -> drop(xs, n - 1)
}
}
}
fn do_take(list, n, acc) {
case n <= 0 {
| True -> reverse(acc)
| False ->
case list {
| [] -> reverse(acc)
| [x | xs] -> do_take(xs, n - 1, [x | acc])
}
}
}
pub fn take(list, n) {
do_take(list, n, [])
}
pub fn new() {
[]
}
pub external fn append(List(a), List(a)) -> List(a) = "lists" "append";
fn do_flatten(lists, acc) {
case lists {
| [] -> acc
| [l | rest] -> do_flatten(rest, append(acc, l))
}
}
pub fn flatten(lists) {
do_flatten(lists, [])
}
pub fn fold(list, acc, fun) {
case list {
| [] -> acc
| [x | rest] -> fold(rest, fun(x, acc), fun)
}
}
pub fn fold_right(list, acc, fun) {
case list {
| [] -> acc
| [x | rest] -> fun(x, fold_right(rest, acc, fun))
}
}
pub fn find(haystack, f) {
case haystack {
| [] -> Error(NotFound)
| [x | rest] ->
case f(x) {
| Ok(x) -> Ok(x)
| _ -> find(rest, f)
}
}
}
pub fn all(list, f) {
case list {
| [] -> True
| [x | rest] ->
case f(x) {
| True -> all(rest, f)
| _ -> False
}
}
}
pub fn any(list, f) {
case list {
| [] -> False
| [ x | rest] ->
case f(x) {
| False -> any(rest, f)
| _ -> True
}
}
}
pub fn zip(l1, l2) {
case {l1, l2} {
| {[], _} -> []
| {_, []} -> []
| {[x1 | rest1], [x2 | rest2] } -> [ {x1, x2} | zip(rest1, rest2) ]
}
}
pub fn strict_zip(l1, l2) {
case length(l1) == length(l2) {
| True -> Ok(zip(l1, l2))
| False -> Error(LengthMismatch)
}
}
pub fn intersperse(list, elem) {
case list {
| [] -> []
| [x | []] -> [x]
| [x | rest] -> [x | [elem | intersperse(rest, elem)]]
}
}
pub fn at(list, i) {
case i < 0 {
| True -> Error(NotFound)
| False ->
case list {
| [] -> Error(NotFound)
| [x | rest] ->
case i == 0 {
| True -> Ok(x)
| False -> at(rest, i - 1)
}
}
}
}
pub fn unique(list) {
case list {
| [] -> []
| [x | rest] -> [x | unique(filter(rest, fn(y) { y != x }))]
}
}
fn merge_sort(a, b) {
case {a, b} {
| {[], _} -> b
| {_, []} -> a
| {[ax | ar], [bx | br]} ->
case ax < bx {
| True -> [ax | merge_sort(ar, b)]
| False -> [bx | merge_sort(a, br)]
}
}
}
pub fn sort(list) {
let list_length = length(list)
case list_length < 2 {
| True -> list
| False ->
let split_length = list_length / 2
let a_list = take(list, split_length)
let b_list = drop(list, split_length)
merge_sort(sort(a_list), sort(b_list))
}
}
pub fn range(start, stop) {
case int:compare(start, stop) {
| order:Eq -> []
| order:Gt -> [start | range(start - 1, stop)]
| order:Lt -> [start | range(start + 1, stop)]
}
}
fn do_repeat(a, times, acc) {
case times <= 0 {
| True -> acc
| False -> do_repeat(a, times - 1, [a | acc])
}
}
pub fn repeat(a, times) {
do_repeat(a, times, [])
}
fn do_split(list, n, taken) {
case n <= 0 {
| True -> {reverse(taken), list}
| False ->
case list {
| [] -> {reverse(taken), []}
| [x | xs] -> do_split(xs, n - 1, [x | taken])
}
}
}
pub fn split(list, n) {
do_split(list, n, [])
}
fn do_split_while(list, f, acc) {
case list {
| [] -> {reverse(acc), []}
| [x | xs] ->
case f(x) {
| False -> {reverse(acc), list}
| _ -> do_split_while(xs, f, [x | acc])
}
}
}
pub fn split_while(list, f) {
do_split_while(list, f, [])
}