diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | gen/src/gleam@list.erl | 25 | ||||
-rw-r--r-- | gen/test/gleam@list_test.erl | 16 | ||||
-rw-r--r-- | src/gleam/list.gleam | 15 | ||||
-rw-r--r-- | test/gleam/list_test.gleam | 30 |
5 files changed, 70 insertions, 18 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index b8ef2de..d48b3cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - Labels have been added to functions throughout the stdlib. - `map.fetch` has been renamed to `map.get` and `map.put` to `map.insert`. +- `list.find` has been renamed `list.find_map` and a new `list.find` has been + introduced. - The `pair` module gains the `map_first`, and `map_second` functions. - The `string` module gains the `compare` function. - The `float` module gains the `max`, and `min` functions. diff --git a/gen/src/gleam@list.erl b/gen/src/gleam@list.erl index 508da27..586a5aa 100644 --- a/gen/src/gleam@list.erl +++ b/gen/src/gleam@list.erl @@ -1,7 +1,7 @@ -module(gleam@list). -compile(no_auto_import). --export([length/1, reverse/1, is_empty/1, contains/2, head/1, tail/1, filter/2, map/2, index_map/2, traverse/2, drop/2, take/2, new/0, append/2, flatten/1, fold/3, fold_right/3, find/2, all/2, any/2, zip/2, strict_zip/2, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2]). +-export([length/1, reverse/1, is_empty/1, contains/2, head/1, tail/1, filter/2, map/2, index_map/2, traverse/2, drop/2, take/2, new/0, append/2, flatten/1, fold/3, fold_right/3, find/2, find_map/2, all/2, any/2, zip/2, strict_zip/2, intersperse/2, at/2, unique/1, sort/2, range/2, repeat/2, split/2, split_while/2, key_find/2]). length(A) -> erlang:length(A). @@ -169,18 +169,33 @@ fold_right(List, Initial, Fun) -> Fun(X, fold_right(Rest, Initial, Fun)) end. -find(Haystack, Predicate) -> +find(Haystack, IsDesired) -> case Haystack of [] -> {error, nil}; [X | Rest] -> - case Predicate(X) of + case IsDesired(X) of + true -> + {ok, X}; + + _ -> + find(Rest, IsDesired) + end + end. + +find_map(Haystack, Fun) -> + case Haystack of + [] -> + {error, nil}; + + [X | Rest] -> + case Fun(X) of {ok, X1} -> {ok, X1}; _ -> - find(Rest, Predicate) + find_map(Rest, Fun) end end. @@ -375,7 +390,7 @@ split_while(List, Predicate) -> do_split_while(List, Predicate, []). key_find(Haystack, Needle) -> - find(Haystack, fun(P) -> case gleam@pair:first(P) =:= Needle of + find_map(Haystack, fun(P) -> case gleam@pair:first(P) =:= Needle of true -> {ok, gleam@pair:second(P)}; diff --git a/gen/test/gleam@list_test.erl b/gen/test/gleam@list_test.erl index ae1f786..6281c9e 100644 --- a/gen/test/gleam@list_test.erl +++ b/gen/test/gleam@list_test.erl @@ -1,7 +1,7 @@ -module(gleam@list_test). -compile(no_auto_import). --export([length_test/0, reverse_test/0, is_empty_test/0, contains_test/0, head_test/0, tail_test/0, filter_test/0, map_test/0, traverse_test/0, drop_test/0, take_test/0, new_test/0, append_test/0, flatten_test/0, fold_test/0, fold_right_test/0, find_test/0, all_test/0, any_test/0, zip_test/0, strict_zip_test/0, intersperse_test/0, at_test/0, unique_test/0, sort_test/0, index_map_test/0, range_test/0, repeat_test/0, split_test/0, split_while_test/0, key_find_test/0]). +-export([length_test/0, reverse_test/0, is_empty_test/0, contains_test/0, head_test/0, tail_test/0, filter_test/0, map_test/0, traverse_test/0, drop_test/0, take_test/0, new_test/0, append_test/0, flatten_test/0, fold_test/0, fold_right_test/0, find_map_test/0, find_test/0, all_test/0, any_test/0, zip_test/0, strict_zip_test/0, intersperse_test/0, at_test/0, unique_test/0, sort_test/0, index_map_test/0, range_test/0, repeat_test/0, split_test/0, split_while_test/0, key_find_test/0]). length_test() -> gleam@expect:equal(gleam@list:length([]), 0), @@ -102,7 +102,7 @@ fold_right_test() -> [1, 2, 3] ). -find_test() -> +find_map_test() -> F = fun(X) -> case X of 2 -> {ok, 4}; @@ -110,9 +110,15 @@ find_test() -> _ -> {error, 0} end end, - gleam@expect:equal(gleam@list:find([1, 2, 3], F), {ok, 4}), - gleam@expect:equal(gleam@list:find([1, 3, 2], F), {ok, 4}), - gleam@expect:equal(gleam@list:find([1, 3], F), {error, nil}). + gleam@expect:equal(gleam@list:find_map([1, 2, 3], F), {ok, 4}), + gleam@expect:equal(gleam@list:find_map([1, 3, 2], F), {ok, 4}), + gleam@expect:equal(gleam@list:find_map([1, 3], F), {error, nil}). + +find_test() -> + IsTwo = fun(X) -> X =:= 2 end, + gleam@expect:equal(gleam@list:find([1, 2, 3], IsTwo), {ok, 2}), + gleam@expect:equal(gleam@list:find([1, 3, 2], IsTwo), {ok, 2}), + gleam@expect:equal(gleam@list:find([1, 3], IsTwo), {error, nil}). all_test() -> gleam@expect:equal( diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 5c9a926..cd4b5ea 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -153,12 +153,23 @@ pub fn find(in haystack, one_that is_desired) { | [] -> Error(Nil) | [x | rest] -> case is_desired(x) { - | Ok(x) -> Ok(x) + | True -> Ok(x) | _ -> find(in: rest, one_that: is_desired) } } } +pub fn find_map(in haystack, with fun) { + case haystack { + | [] -> Error(Nil) + | [x | rest] -> + case fun(x) { + | Ok(x) -> Ok(x) + | _ -> find_map(in: rest, with: fun) + } + } +} + pub fn all(in list, satisfying predicate) { case list { | [] -> True @@ -307,7 +318,7 @@ pub fn split_while(list list, while predicate) { } pub fn key_find(in haystack, find needle) { - find(haystack, fn(p) { + find_map(haystack, fn(p) { case pair.first(p) == needle { | True -> p |> pair.second |> Ok | False -> Error(Nil) diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam index 4be1795..d4322fe 100644 --- a/test/gleam/list_test.gleam +++ b/test/gleam/list_test.gleam @@ -142,11 +142,11 @@ pub fn fold_test() { pub fn fold_right_test() { [1, 2, 3] - |> list.fold_right(_, [], fn(x, acc) { [x | acc] }) - |> expect.equal(_, [1, 2, 3]) + |> list.fold_right(_, from: [], with: fn(x, acc) { [x | acc] }) + |> expect.equal(_, [1, 2, 3]) } -pub fn find_test() { +pub fn find_map_test() { let f = fn(x) { case x { | 2 -> Ok(4) @@ -155,15 +155,33 @@ pub fn find_test() { } [1, 2, 3] - |> list.find(_, f) + |> list.find_map(_, with: f) |> expect.equal(_, Ok(4)) [1, 3, 2] - |> list.find(_, f) + |> list.find_map(_, with: f) |> expect.equal(_, Ok(4)) [1, 3] - |> list.find(_, f) + |> list.find_map(_, with: f) + |> expect.equal(_, Error(Nil)) +} + +pub fn find_test() { + let is_two = fn(x) { + x == 2 + } + + [1, 2, 3] + |> list.find(_, one_that: is_two) + |> expect.equal(_, Ok(2)) + + [1, 3, 2] + |> list.find(_, one_that: is_two) + |> expect.equal(_, Ok(2)) + + [1, 3] + |> list.find(_, one_that: is_two) |> expect.equal(_, Error(Nil)) } |