aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGiacomo Cavalieri <giacomo.cavalieri@icloud.com>2024-10-10 13:21:06 +0200
committerLouis Pilfold <louis@lpil.uk>2024-10-10 15:06:25 +0100
commit6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5 (patch)
tree62c1252854944c8ad0d67ea8782b5a9d8f4ed241 /src
parent819ba370d0987c0494680ea258aaec4492adbdc6 (diff)
downloadgleam_stdlib-6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5.tar.gz
gleam_stdlib-6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5.zip
refactor list
Diffstat (limited to 'src')
-rw-r--r--src/gleam/list.gleam211
1 files changed, 107 insertions, 104 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index 32cb38b..ea616de 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -123,11 +123,11 @@ pub fn count(list: List(a), where predicate: fn(a) -> Bool) -> Int {
/// ```
///
@external(erlang, "lists", "reverse")
-pub fn reverse(xs: List(a)) -> List(a) {
- do_reverse(xs, [])
+pub fn reverse(list: List(a)) -> List(a) {
+ do_reverse(list, [])
}
-fn do_reverse(remaining, accumulator) {
+fn do_reverse(remaining: List(a), accumulator: List(a)) -> List(a) {
case remaining {
[] -> accumulator
[item, ..rest] -> do_reverse(rest, [item, ..accumulator])
@@ -250,13 +250,11 @@ pub fn first(list: List(a)) -> Result(a, Nil) {
pub fn rest(list: List(a)) -> Result(List(a), Nil) {
case list {
[] -> Error(Nil)
- [_, ..xs] -> Ok(xs)
+ [_, ..rest] -> Ok(rest)
}
}
-fn update_group(
- f: fn(element) -> key,
-) -> fn(Dict(key, List(element)), element) -> Dict(key, List(element)) {
+fn update_group(f: fn(a) -> k) -> fn(Dict(k, List(a)), a) -> Dict(k, List(a)) {
fn(groups, elem) {
case dict.get(groups, f(elem)) {
Ok(existing) -> dict.insert(groups, f(elem), [elem, ..existing])
@@ -304,12 +302,12 @@ pub fn group(list: List(v), by key: fn(v) -> k) -> Dict(k, List(v)) {
fn do_filter(list: List(a), fun: fn(a) -> Bool, acc: List(a)) -> List(a) {
case list {
[] -> reverse(acc)
- [x, ..xs] -> {
- let new_acc = case fun(x) {
- True -> [x, ..acc]
+ [first, ..rest] -> {
+ let new_acc = case fun(first) {
+ True -> [first, ..acc]
False -> acc
}
- do_filter(xs, fun, new_acc)
+ do_filter(rest, fun, new_acc)
}
}
}
@@ -340,12 +338,12 @@ fn do_filter_map(
) -> List(b) {
case list {
[] -> reverse(acc)
- [x, ..xs] -> {
- let new_acc = case fun(x) {
- Ok(x) -> [x, ..acc]
+ [first, ..rest] -> {
+ let new_acc = case fun(first) {
+ Ok(first) -> [first, ..acc]
Error(_) -> acc
}
- do_filter_map(xs, fun, new_acc)
+ do_filter_map(rest, fun, new_acc)
}
}
}
@@ -372,7 +370,7 @@ pub fn filter_map(list: List(a), with fun: fn(a) -> Result(b, e)) -> List(b) {
fn do_map(list: List(a), fun: fn(a) -> b, acc: List(b)) -> List(b) {
case list {
[] -> reverse(acc)
- [x, ..xs] -> do_map(xs, fun, [fun(x), ..acc])
+ [first, ..rest] -> do_map(rest, fun, [fun(first), ..acc])
}
}
@@ -437,10 +435,10 @@ fn do_map2(
///
pub fn map_fold(
over list: List(a),
- from acc: acc,
+ from initial: acc,
with fun: fn(acc, a) -> #(acc, b),
) -> #(acc, List(b)) {
- fold(over: list, from: #(acc, []), with: fn(acc, item) {
+ fold(over: list, from: #(initial, []), with: fn(acc, item) {
let #(current_acc, items) = acc
let #(next_acc, next_item) = fun(current_acc, item)
#(next_acc, [next_item, ..items])
@@ -456,9 +454,9 @@ fn do_index_map(
) -> List(b) {
case list {
[] -> reverse(acc)
- [x, ..xs] -> {
- let acc = [fun(x, index), ..acc]
- do_index_map(xs, fun, index + 1, acc)
+ [first, ..rest] -> {
+ let acc = [fun(first, index), ..acc]
+ do_index_map(rest, fun, index + 1, acc)
}
}
}
@@ -487,9 +485,9 @@ fn do_try_map(
) -> Result(List(b), e) {
case list {
[] -> Ok(reverse(acc))
- [x, ..xs] ->
- case fun(x) {
- Ok(y) -> do_try_map(xs, fun, [y, ..acc])
+ [first, ..rest] ->
+ case fun(first) {
+ Ok(first) -> do_try_map(rest, fun, [first, ..acc])
Error(error) -> Error(error)
}
}
@@ -560,7 +558,7 @@ pub fn drop(from list: List(a), up_to n: Int) -> List(a) {
False ->
case list {
[] -> []
- [_, ..xs] -> drop(xs, n - 1)
+ [_, ..rest] -> drop(rest, n - 1)
}
}
}
@@ -571,7 +569,7 @@ fn do_take(list: List(a), n: Int, acc: List(a)) -> List(a) {
False ->
case list {
[] -> reverse(acc)
- [x, ..xs] -> do_take(xs, n - 1, [x, ..acc])
+ [first, ..rest] -> do_take(rest, n - 1, [first, ..acc])
}
}
}
@@ -799,11 +797,11 @@ fn do_index_fold(
/// ```
///
pub fn index_fold(
- over over: List(a),
+ over list: List(a),
from initial: acc,
with fun: fn(acc, a, Int) -> acc,
) -> acc {
- do_index_fold(over, initial, fun, 0)
+ do_index_fold(list, initial, fun, 0)
}
/// A variant of fold that might fail.
@@ -826,14 +824,14 @@ pub fn index_fold(
/// ```
///
pub fn try_fold(
- over collection: List(a),
- from accumulator: acc,
+ over list: List(a),
+ from initial: acc,
with fun: fn(acc, a) -> Result(acc, e),
) -> Result(acc, e) {
- case collection {
- [] -> Ok(accumulator)
+ case list {
+ [] -> Ok(initial)
[first, ..rest] ->
- case fun(accumulator, first) {
+ case fun(initial, first) {
Ok(result) -> try_fold(rest, result, fun)
Error(_) as error -> error
}
@@ -865,14 +863,14 @@ pub type ContinueOrStop(a) {
/// ```
///
pub fn fold_until(
- over collection: List(a),
- from accumulator: acc,
+ over list: List(a),
+ from initial: acc,
with fun: fn(acc, a) -> ContinueOrStop(acc),
) -> acc {
- case collection {
- [] -> accumulator
+ case list {
+ [] -> initial
[first, ..rest] ->
- case fun(accumulator, first) {
+ case fun(initial, first) {
Continue(next_accumulator) -> fold_until(rest, next_accumulator, fun)
Stop(b) -> b
}
@@ -902,10 +900,10 @@ pub fn fold_until(
/// ```
///
pub fn find(
- in haystack: List(a),
+ in list: List(a),
one_that is_desired: fn(a) -> Bool,
) -> Result(a, Nil) {
- case haystack {
+ case list {
[] -> Error(Nil)
[x, ..rest] ->
case is_desired(x) {
@@ -938,10 +936,10 @@ pub fn find(
/// ```
///
pub fn find_map(
- in haystack: List(a),
+ in list: List(a),
with fun: fn(a) -> Result(b, c),
) -> Result(b, Nil) {
- case haystack {
+ case list {
[] -> Error(Nil)
[x, ..rest] ->
case fun(x) {
@@ -1020,9 +1018,10 @@ pub fn any(in list: List(a), satisfying predicate: fn(a) -> Bool) -> Bool {
}
}
-fn do_zip(xs: List(a), ys: List(b), acc: List(#(a, b))) -> List(#(a, b)) {
- case xs, ys {
- [x, ..xs], [y, ..ys] -> do_zip(xs, ys, [#(x, y), ..acc])
+fn do_zip(one: List(a), other: List(b), acc: List(#(a, b))) -> List(#(a, b)) {
+ case one, other {
+ [first_one, ..rest_one], [first_other, ..rest_other] ->
+ do_zip(rest_one, rest_other, [#(first_one, first_other), ..acc])
_, _ -> reverse(acc)
}
}
@@ -1094,10 +1093,15 @@ pub fn strict_zip(
}
}
-fn do_unzip(input, xs, ys) {
+fn do_unzip(
+ input: List(#(a, b)),
+ one: List(a),
+ other: List(b),
+) -> #(List(a), List(b)) {
case input {
- [] -> #(reverse(xs), reverse(ys))
- [#(x, y), ..rest] -> do_unzip(rest, [x, ..xs], [y, ..ys])
+ [] -> #(reverse(one), reverse(other))
+ [#(first_one, first_other), ..rest] ->
+ do_unzip(rest, [first_one, ..one], [first_other, ..other])
}
}
@@ -1464,10 +1468,10 @@ fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) {
}
}
-fn do_repeat(a: a, times: Int, acc: List(a)) -> List(a) {
+fn do_repeat(item: a, times: Int, acc: List(a)) -> List(a) {
case times <= 0 {
True -> acc
- False -> do_repeat(a, times - 1, [a, ..acc])
+ False -> do_repeat(item, times - 1, [item, ..acc])
}
}
@@ -1495,7 +1499,7 @@ fn do_split(list: List(a), n: Int, taken: List(a)) -> #(List(a), List(a)) {
False ->
case list {
[] -> #(reverse(taken), [])
- [x, ..xs] -> do_split(xs, n - 1, [x, ..taken])
+ [first, ..rest] -> do_split(rest, n - 1, [first, ..taken])
}
}
}
@@ -1533,10 +1537,10 @@ fn do_split_while(
) -> #(List(a), List(a)) {
case list {
[] -> #(reverse(acc), [])
- [x, ..xs] ->
- case f(x) {
+ [first, ..rest] ->
+ case f(first) {
False -> #(reverse(acc), list)
- _ -> do_split_while(xs, f, [x, ..acc])
+ _ -> do_split_while(rest, f, [first, ..acc])
}
}
}
@@ -1668,14 +1672,18 @@ fn do_pop(haystack, predicate, checked) {
/// ```
///
pub fn pop(
- in haystack: List(a),
+ in list: List(a),
one_that is_desired: fn(a) -> Bool,
) -> Result(#(a, List(a)), Nil) {
- do_pop(haystack, is_desired, [])
+ do_pop(list, is_desired, [])
}
-fn do_pop_map(haystack, mapper, checked) {
- case haystack {
+fn do_pop_map(
+ list: List(a),
+ mapper: fn(a) -> Result(b, e),
+ checked: List(a),
+) -> Result(#(b, List(a)), Nil) {
+ case list {
[] -> Error(Nil)
[x, ..rest] ->
case mapper(x) {
@@ -1737,11 +1745,8 @@ pub fn pop_map(
/// // -> Error(Nil)
/// ```
///
-pub fn key_pop(
- haystack: List(#(k, v)),
- key: k,
-) -> Result(#(v, List(#(k, v))), Nil) {
- pop_map(haystack, fn(entry) {
+pub fn key_pop(list: List(#(k, v)), key: k) -> Result(#(v, List(#(k, v))), Nil) {
+ pop_map(list, fn(entry) {
let #(k, v) = entry
case k {
k if k == key -> Ok(v)
@@ -1767,7 +1772,7 @@ pub fn key_pop(
/// // -> [#(5, 0), #(4, 1), #(1, 100)]
/// ```
///
-pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) {
+pub fn key_set(list: List(#(k, v)), key: k, value: v) -> List(#(k, v)) {
case list {
[] -> [#(key, value)]
[#(k, _), ..rest] if k == key -> [#(key, value), ..rest]
@@ -1792,9 +1797,9 @@ pub fn key_set(list: List(#(a, b)), key: a, value: b) -> List(#(a, b)) {
pub fn each(list: List(a), f: fn(a) -> b) -> Nil {
case list {
[] -> Nil
- [x, ..xs] -> {
- f(x)
- each(xs, f)
+ [first, ..rest] -> {
+ f(first)
+ each(rest, f)
}
}
}
@@ -1821,9 +1826,9 @@ pub fn try_each(
) -> Result(Nil, e) {
case list {
[] -> Ok(Nil)
- [x, ..xs] ->
- case fun(x) {
- Ok(_) -> try_each(over: xs, with: fun)
+ [first, ..rest] ->
+ case fun(first) {
+ Ok(_) -> try_each(over: rest, with: fun)
Error(e) -> Error(e)
}
}
@@ -1832,10 +1837,10 @@ pub fn try_each(
fn do_partition(list, categorise, trues, falses) {
case list {
[] -> #(reverse(trues), reverse(falses))
- [x, ..xs] ->
- case categorise(x) {
- True -> do_partition(xs, categorise, [x, ..trues], falses)
- False -> do_partition(xs, categorise, trues, [x, ..falses])
+ [first, ..rest] ->
+ case categorise(first) {
+ True -> do_partition(rest, categorise, [first, ..trues], falses)
+ False -> do_partition(rest, categorise, trues, [first, ..falses])
}
}
}
@@ -1868,14 +1873,12 @@ pub fn partition(
/// // -> [[1, 2], [2, 1]]
/// ```
///
-pub fn permutations(l: List(a)) -> List(List(a)) {
- case l {
+pub fn permutations(list: List(a)) -> List(List(a)) {
+ case list {
[] -> [[]]
_ ->
- l
- |> index_map(fn(i, i_idx) {
- l
- |> index_fold([], fn(acc, j, j_idx) {
+ index_map(list, fn(i, i_idx) {
+ index_fold(list, [], fn(acc, j, j_idx) {
case i_idx == j_idx {
True -> acc
False -> [j, ..acc]
@@ -1889,11 +1892,11 @@ pub fn permutations(l: List(a)) -> List(List(a)) {
}
}
-fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) {
- let window = take(l, n)
+fn do_window(acc: List(List(a)), list: List(a), n: Int) -> List(List(a)) {
+ let window = take(list, n)
case length(window) == n {
- True -> do_window([window, ..acc], drop(l, 1), n)
+ True -> do_window([window, ..acc], drop(list, 1), n)
False -> acc
}
}
@@ -1912,10 +1915,10 @@ fn do_window(acc: List(List(a)), l: List(a), n: Int) -> List(List(a)) {
/// // -> []
/// ```
///
-pub fn window(l: List(a), by n: Int) -> List(List(a)) {
+pub fn window(list: List(a), by n: Int) -> List(List(a)) {
case n <= 0 {
True -> []
- False -> do_window([], l, n) |> reverse
+ False -> do_window([], list, n) |> reverse
}
}
@@ -1933,8 +1936,8 @@ pub fn window(l: List(a), by n: Int) -> List(List(a)) {
/// // -> []
/// ```
///
-pub fn window_by_2(l: List(a)) -> List(#(a, a)) {
- zip(l, drop(l, 1))
+pub fn window_by_2(list: List(a)) -> List(#(a, a)) {
+ zip(list, drop(list, 1))
}
/// Drops the first elements in a given list for which the predicate function returns `True`.
@@ -1952,10 +1955,10 @@ pub fn drop_while(
) -> List(a) {
case list {
[] -> []
- [x, ..xs] ->
- case predicate(x) {
- True -> drop_while(xs, predicate)
- False -> [x, ..xs]
+ [first, ..rest] ->
+ case predicate(first) {
+ True -> drop_while(rest, predicate)
+ False -> [first, ..rest]
}
}
}
@@ -1993,8 +1996,8 @@ pub fn take_while(
fn do_chunk(
list: List(a),
- f: fn(a) -> key,
- previous_key: key,
+ f: fn(a) -> k,
+ previous_key: k,
current_chunk: List(a),
acc: List(List(a)),
) -> List(List(a)) {
@@ -2023,7 +2026,7 @@ fn do_chunk(
/// // -> [[1], [2, 2], [3], [4, 4, 6], [7, 7]]
/// ```
///
-pub fn chunk(in list: List(a), by f: fn(a) -> key) -> List(List(a)) {
+pub fn chunk(in list: List(a), by f: fn(a) -> k) -> List(List(a)) {
case list {
[] -> []
[first, ..rest] -> do_chunk(rest, f, f(first), [first], [])
@@ -2111,9 +2114,9 @@ fn do_scan(
) -> List(acc) {
case list {
[] -> reverse(accumulated)
- [x, ..xs] -> {
- let next = fun(accumulator, x)
- do_scan(xs, next, [next, ..accumulated], fun)
+ [first, ..rest] -> {
+ let next = fun(accumulator, first)
+ do_scan(rest, next, [next, ..accumulated], fun)
}
}
}
@@ -2180,11 +2183,11 @@ pub fn combinations(items: List(a), by n: Int) -> List(List(a)) {
_ ->
case items {
[] -> []
- [x, ..xs] -> {
+ [first, ..rest] -> {
let first_combinations =
- map(combinations(xs, n - 1), with: fn(com) { [x, ..com] })
+ map(combinations(rest, n - 1), with: fn(com) { [first, ..com] })
|> reverse
- fold(first_combinations, combinations(xs, n), fn(acc, c) {
+ fold(first_combinations, combinations(rest, n), fn(acc, c) {
[c, ..acc]
})
}
@@ -2195,9 +2198,9 @@ pub fn combinations(items: List(a), by n: Int) -> List(List(a)) {
fn do_combination_pairs(items: List(a)) -> List(List(#(a, a))) {
case items {
[] -> []
- [x, ..xs] -> {
- let first_combinations = map(xs, with: fn(other) { #(x, other) })
- [first_combinations, ..do_combination_pairs(xs)]
+ [first, ..rest] -> {
+ let first_combinations = map(rest, with: fn(other) { #(first, other) })
+ [first_combinations, ..do_combination_pairs(rest)]
}
}
}
@@ -2254,7 +2257,7 @@ pub fn transpose(list_of_list: List(List(a))) -> List(List(a)) {
case list_of_list {
[] -> []
- [[], ..xss] -> transpose(xss)
+ [[], ..rest] -> transpose(rest)
rows -> {
let firsts =
rows