diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gleam/iterator.gleam | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index 5865646..c13a10e 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -386,6 +386,56 @@ pub fn map(over iterator: Iterator(a), with f: fn(a) -> b) -> Iterator(b) { |> Iterator } +fn do_map2( + continuation1: fn() -> Action(a), + continuation2: fn() -> Action(b), + with fun: fn(a, b) -> c, +) -> fn() -> Action(c) { + fn() { + case continuation1() { + Stop -> Stop + Continue(a, next_a) -> + case continuation2() { + Stop -> Stop + Continue(b, next_b) -> + Continue(fun(a, b), do_map2(next_a, next_b, fun)) + } + } + } +} + +/// Combines two interators into a single one using the given function. +/// +/// If an iterator is longer than the other the extra elements are dropped. +/// +/// This function does not evaluate the elements of the two iterators, the +/// computation is performed when the resulting iterator is later run. +/// +/// ## Examples +/// +/// ```gleam +/// let first = from_list([1, 2, 3]) +/// let second = from_list([4, 5, 6]) +/// map2(first, second, fn(x, y) { x + y }) |> to_list +/// // -> [5, 7, 9] +/// ``` +/// +/// ```gleam +/// let first = from_list([1, 2]) +/// let second = from_list(["a", "b", "c"]) +/// map2(first, second, fn(i, x) { #(i, x) }) |> to_list +/// // -> [#(1, "a"), #(2, "b")] +/// ``` +/// +pub fn map2( + iterator1: Iterator(a), + iterator2: Iterator(b), + with fun: fn(a, b) -> c, +) -> Iterator(c) { + do_map2(iterator1.continuation, iterator2.continuation, fun) + |> Iterator +} + fn do_append(first: fn() -> Action(a), second: fn() -> Action(a)) -> Action(a) { case first() { Continue(e, first) -> Continue(e, fn() { do_append(first, second) }) |