aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Attard <robert.attard@mail.mcgill.ca>2021-07-30 14:12:14 -0400
committerLouis Pilfold <louis@lpil.uk>2021-08-11 20:36:55 +0100
commit0b70df9a3f1122113a856b0ad749b51862e415ca (patch)
treeb815fa7853d72e2c39386232b7127f54db29b014 /src
parentdda6adf8060854eaee7178c8c270c74b6a2dcd63 (diff)
downloadgleam_stdlib-0b70df9a3f1122113a856b0ad749b51862e415ca.tar.gz
gleam_stdlib-0b70df9a3f1122113a856b0ad749b51862e415ca.zip
iterator.try_fold
Diffstat (limited to 'src')
-rw-r--r--src/gleam/iterator.gleam41
-rw-r--r--src/gleam/list.gleam9
2 files changed, 45 insertions, 5 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam
index 2421657..30fdcf9 100644
--- a/src/gleam/iterator.gleam
+++ b/src/gleam/iterator.gleam
@@ -1078,3 +1078,44 @@ pub fn fold_until(
iterator.continuation
|> do_fold_until(f, initial)
}
+
+fn do_try_fold(
+ over continuation: fn() -> Action(a),
+ with f: fn(a, acc) -> Result(acc, err),
+ from accumulator: acc,
+) -> Result(acc, err) {
+ case continuation() {
+ Stop -> Ok(accumulator)
+ Continue(elem, next) -> {
+ try accumulator = f(elem, accumulator)
+ do_try_fold(next, f, accumulator)
+ }
+ }
+}
+
+/// A variant of fold that might fail.
+///
+///
+/// The folding function should return `Result(accumulator, error)
+/// If the returned value is `Ok(accumulator)` try_fold will try the next value in the list.
+/// If the returned value is `Error(error)` try_fold will stop and return that error.
+///
+/// ## Examples
+///
+/// > [1, 2, 3, 4]
+/// > |> iterator.from_list()
+/// > |> try_fold(0, fn(i, acc) {
+/// > case i < 3 {
+/// > True -> Ok(acc + i)
+/// > False -> Error(Nil)
+/// > }
+/// > })
+/// Error(Nil)
+///
+pub fn try_fold(
+ over iterator: Iterator(e),
+ from initial: acc,
+ with f: fn(e, acc) -> Result(acc, err),
+) -> Result(acc, err) {
+ do_try_fold(iterator.continuation, f, initial)
+}
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam
index 62e69f9..5cfe4a5 100644
--- a/src/gleam/list.gleam
+++ b/src/gleam/list.gleam
@@ -614,11 +614,10 @@ pub fn try_fold(
) -> Result(b, e) {
case collection {
[] -> Ok(accumulator)
- [first, ..rest] ->
- case fun(first, accumulator) {
- Ok(next_accumulator) -> try_fold(rest, next_accumulator, fun)
- Error(err) -> Error(err)
- }
+ [first, ..rest] -> {
+ try accumulator = fun(first, accumulator)
+ try_fold(rest, accumulator, fun)
+ }
}
}