diff options
author | Giacomo Cavalieri <giacomo.cavalieri@icloud.com> | 2024-10-10 13:21:06 +0200 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2024-10-10 15:06:25 +0100 |
commit | 6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5 (patch) | |
tree | 62c1252854944c8ad0d67ea8782b5a9d8f4ed241 /src | |
parent | 819ba370d0987c0494680ea258aaec4492adbdc6 (diff) | |
download | gleam_stdlib-6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5.tar.gz gleam_stdlib-6bdd8c74a8bef07db0e43a1bd3f7e9d5bc50b2b5.zip |
refactor list
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/list.gleam | 211 |
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 |