diff options
author | Marcin Puc <tranzystorek.io@protonmail.com> | 2022-12-15 07:50:11 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2022-12-22 20:18:07 +0000 |
commit | 0053dbc726174937bfaf342bad013bd90e6a8e5c (patch) | |
tree | a76e229533a91ec9af42a7a3a13b3694a6c36afd /src | |
parent | 690a47dd49e36e4d117d0ed7918af2c5b538096e (diff) | |
download | gleam_stdlib-0053dbc726174937bfaf342bad013bd90e6a8e5c.tar.gz gleam_stdlib-0053dbc726174937bfaf342bad013bd90e6a8e5c.zip |
iterator: add transform()
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/iterator.gleam | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index 9b7b0f3..7a69a5b 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -125,6 +125,49 @@ pub fn from_list(list: List(element)) -> Iterator(element) { } // Consuming Iterators +fn do_transform( + continuation: fn() -> Action(a), + state: acc, + f: fn(acc, a) -> Step(b, acc), +) -> fn() -> Action(b) { + fn() { + case continuation() { + Stop -> Stop + Continue(el, next) -> + case f(state, el) { + Done -> Stop + Next(yield, next_state) -> + Continue(yield, do_transform(next, next_state, f)) + } + } + } +} + +/// Creates an iterator from an existing iterator +/// and a stateful function that may short-circuit. +/// +/// `f` takes arguments `acc` for current state and `el` for current element from underlying iterator, +/// and returns either `Next` with yielded element and new state value, or `Done` to halt the iterator. +/// +/// ## Examples +/// +/// Approximate implementation of `index` in terms of `transform`: +/// +/// ```gleam +/// > from_list(["a", "b", "c"]) +/// > |> transform(0, fn(i, el) { Next(#(i, el), i + 1) }) +/// > |> to_list +/// [#(0, "a"), #(1, "b"), #(2, "c")] +/// ``` +pub fn transform( + over iterator: Iterator(a), + from initial: acc, + with f: fn(acc, a) -> Step(b, acc), +) -> Iterator(b) { + do_transform(iterator.continuation, initial, f) + |> Iterator +} + fn do_fold( continuation: fn() -> Action(e), f: fn(acc, e) -> acc, |