diff options
author | Robert Attard <robert.attard@mail.mcgill.ca> | 2021-07-30 14:12:14 -0400 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-08-11 20:36:55 +0100 |
commit | 0b70df9a3f1122113a856b0ad749b51862e415ca (patch) | |
tree | b815fa7853d72e2c39386232b7127f54db29b014 /src | |
parent | dda6adf8060854eaee7178c8c270c74b6a2dcd63 (diff) | |
download | gleam_stdlib-0b70df9a3f1122113a856b0ad749b51862e415ca.tar.gz gleam_stdlib-0b70df9a3f1122113a856b0ad749b51862e415ca.zip |
iterator.try_fold
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/iterator.gleam | 41 | ||||
-rw-r--r-- | src/gleam/list.gleam | 9 |
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) + } } } |