aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiacomo Cavalieri <giacomo.cavalieri@icloud.com>2023-05-08 12:12:55 +0200
committerLouis Pilfold <louis@lpil.uk>2023-05-10 18:52:46 +0100
commitd20282d999be8db6a5cc43be540b0eeb6dda8d15 (patch)
treec58d8502bfd281a54bee2713c80da11dd37dc655
parent227c5954a77a7d42446ed100dd8b10cf4055408a (diff)
downloadgleam_stdlib-d20282d999be8db6a5cc43be540b0eeb6dda8d15.tar.gz
gleam_stdlib-d20282d999be8db6a5cc43be540b0eeb6dda8d15.zip
Change `partition`'s return type to return both oks and errors in a pair
-rw-r--r--src/gleam/result.gleam44
-rw-r--r--test/gleam/result_test.gleam18
2 files changed, 15 insertions, 47 deletions
diff --git a/src/gleam/result.gleam b/src/gleam/result.gleam
index 4f3ecd9..6d65459 100644
--- a/src/gleam/result.gleam
+++ b/src/gleam/result.gleam
@@ -366,48 +366,26 @@ pub fn all(results: List(Result(a, e))) -> Result(List(a), e) {
list.try_map(results, fn(x) { x })
}
-/// Combines a list of results into a single result.
-/// If all elements in the list are `Ok` then returns an `Ok` holding the list of values.
-/// If any element is `Error` then returns an `Error` holding the list of all errors.
+/// Given a list of results, returns a pair where the first element is a list
+/// of all the values inside `Ok` and the second element is a list with all the
+/// values inside `Error`.
///
/// ## Examples
///
/// ```gleam
-/// > partition([Ok(1), Ok(2)])
-/// Ok([1, 2])
-/// ```
-///
-/// ```gleam
-/// > partition([Ok(1), Error("a"), Error("b")])
-/// Error(["a", "b"])
+/// > partition([Ok(1), Error("a"), Error("b"), Ok(2)])
+/// #([1, 2], ["a", "b"])
/// ```
///
-pub fn partition(results: List(Result(a, e))) -> Result(List(a), List(e)) {
- case results {
- [] -> Ok([])
- [Ok(a), ..rest] -> do_partition(rest, Ok([a]))
- [Error(b), ..rest] -> do_partition(rest, Error([b]))
- }
+pub fn partition(results: List(Result(a, e))) -> #(List(a), List(e)) {
+ do_partition(results, [], [])
}
-fn do_partition(results: List(Result(a, b)), acc: Result(List(a), List(b))) {
+fn do_partition(results: List(Result(a, e)), oks: List(a), errors: List(e)) {
case results {
- [] ->
- acc
- |> map(list.reverse)
- |> map_error(list.reverse)
-
- [Ok(a), ..rest] ->
- case acc {
- Ok(all_as) -> do_partition(rest, Ok([a, ..all_as]))
- Error(all_bs) -> do_partition(rest, Error(all_bs))
- }
-
- [Error(b), ..rest] ->
- case acc {
- Ok(_) -> do_partition(rest, Error([b]))
- Error(all_bs) -> do_partition(rest, Error([b, ..all_bs]))
- }
+ [] -> #(list.reverse(oks), list.reverse(errors))
+ [Ok(a), ..rest] -> do_partition(rest, [a, ..oks], errors)
+ [Error(e), ..rest] -> do_partition(rest, oks, [e, ..errors])
}
}
diff --git a/test/gleam/result_test.gleam b/test/gleam/result_test.gleam
index b35034b..951ef2a 100644
--- a/test/gleam/result_test.gleam
+++ b/test/gleam/result_test.gleam
@@ -199,36 +199,26 @@ pub fn all_test() {
pub fn partition_test() {
[]
|> result.partition
- |> should.equal(Ok([]))
+ |> should.equal(#([], []))
[Ok(1), Ok(2), Ok(3)]
|> result.partition
- |> should.equal(Ok([1, 2, 3]))
+ |> should.equal(#([1, 2, 3], []))
[Error("a"), Error("b"), Error("c")]
|> result.partition
- |> should.equal(Error(["a", "b", "c"]))
-
- [Error("a"), Ok(1), Ok(2)]
- |> result.partition
- |> should.equal(Error(["a"]))
-
- [Ok(1), Ok(2), Error("a")]
- |> result.partition
- |> should.equal(Error(["a"]))
+ |> should.equal(#([], ["a", "b", "c"]))
[Ok(1), Error("a"), Ok(2), Error("b"), Error("c")]
|> result.partition
- |> should.equal(Error(["a", "b", "c"]))
+ |> should.equal(#([1, 2], ["a", "b", "c"]))
// TCO test
list.repeat(Ok(1), 1_000_000)
|> result.partition
- |> should.be_ok
list.repeat(Error("a"), 1_000_000)
|> result.partition
- |> should.be_error
}
pub fn replace_error_test() {