diff options
author | Marcin Puc <5671049+tranzystorek-io@users.noreply.github.com> | 2021-03-10 10:47:22 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-10 09:47:22 +0000 |
commit | 1643c557b5e7e5fcbaf70a689a9b9d8f74e3ee83 (patch) | |
tree | 261ff4f666a9fa439c7ad17e5cbf9c24a87f15f2 /src | |
parent | 1f693fae46e607d6ba811f7d01a9b903f0762420 (diff) | |
download | gleam_stdlib-1643c557b5e7e5fcbaf70a689a9b9d8f74e3ee83.tar.gz gleam_stdlib-1643c557b5e7e5fcbaf70a689a9b9d8f74e3ee83.zip |
Add iterator.scan (#173)
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/iterator.gleam | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index 010d82a..96fd848 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -535,6 +535,22 @@ pub fn iterate( unfold(initial, fn(element) { Next(element, f(element)) }) } +fn do_scan( + continuation: fn() -> Action(element), + accumulator: acc, + f: fn(element, acc) -> acc, +) -> fn() -> Action(acc) { + fn() { + case continuation() { + Continue(el, next) -> { + let accumulated = f(el, accumulator) + Continue(accumulated, do_scan(next, accumulated, f)) + } + Stop -> Stop + } + } +} + fn do_zip( left: fn() -> Action(a), right: fn() -> Action(b), @@ -552,6 +568,26 @@ fn do_zip( } } +/// Creates an iterator from an existing iterator and a stateful function. +/// +/// Specifically, this behaves like `fold`, but yields intermediate results. +/// +/// ## Examples +/// +/// Generate a sequence of partial sums: +/// > from_list([1, 2, 3, 4, 5]) |> scan(from: 0, with: fn(el, acc) { acc + el }) |> to_list +/// [1, 3, 6, 10, 15] +/// +pub fn scan( + over iterator: Iterator(element), + from initial: acc, + with f: fn(element, acc) -> acc, +) -> Iterator(acc) { + iterator.continuation + |> do_scan(initial, f) + |> Iterator +} + /// Zips two iterators together, emitting values from both /// until the shorter one runs out. /// |