diff options
-rw-r--r-- | CHANGELOG.md | 2 | ||||
-rw-r--r-- | src/gleam/list.gleam | 18 | ||||
-rw-r--r-- | test/gleam/list_test.gleam | 14 |
3 files changed, 33 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1362050..c74721f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ - The `result` module gains the `lazy_or`, `lazy_unwrap`, and `replace_error` functions. - The `bool` module gains the `nand`, `nor`, `exclusive_nor`, and `exclusive_or` functions. - The `bit_builder` module gains the `from_string_builder` function. -- The `list` modules gains the `index_fold`, and `permutations` functions. +- The `list` modules gains the `index_fold`, `permutations`, and `try_fold` functions. - Breaking change in `queue.from_list`. The head element in the list becomes the first element in the queue. - Fix `queue.pop_back` and `queue.pop_front` diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index 4109df5..b156b3f 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -479,6 +479,24 @@ pub fn index_fold( ) } +/// A variant of fold that allows to stop folding earlier. +/// +/// The folding function should return `Result(accumulator, accumulator) +/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list. +/// If the returned value is `Error(accumulator)` try_fold will stop and return that accumulator. +/// +/// ## Examples +/// +/// ``` +/// [1, 2, 3, 4] +/// |> try_fold(0, fn(i, acc) { +/// case i < 3 { +/// True -> Ok(acc + i) +/// False -> Error(acc) +/// } +/// }) +/// ``` +/// pub fn try_fold( over collection: List(a), from accumulator: b, diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam index 1c32878..dfc9693 100644 --- a/test/gleam/list_test.gleam +++ b/test/gleam/list_test.gleam @@ -177,6 +177,20 @@ pub fn index_fold_test() { |> should.equal([tuple(2, "c"), tuple(1, "b"), tuple(0, "a")]) } +pub fn try_fold_test() { + [1, 2, 3] + |> list.try_fold( + [], + fn(i, acc) { + case i < 3 { + True -> Ok([i, ..acc]) + False -> Error(acc) + } + }, + ) + |> should.equal([2, 1]) +} + pub fn find_map_test() { let f = fn(x) { case x { |