diff options
-rw-r--r-- | src/gleam/iterator.gleam | 43 | ||||
-rw-r--r-- | src/gleam/string.gleam | 1 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 6 |
3 files changed, 25 insertions, 25 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index 6db10e0..6e0bf31 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -15,7 +15,7 @@ type Action(element) { /// As a lazy data structure no work is done when an iterator is filters, /// mapped, etc, instead a new iterator is returned with these transformations /// applied to the stream. Once the stream has all the required transformations -/// applied it can be evaluated using functions such as `fold` and `take`. +/// applied it can be evaluated using functions such as `fold` and `to_list`. /// pub opaque type Iterator(element) { Iterator(continuation: fn() -> Action(element)) @@ -196,42 +196,35 @@ pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { } } -fn do_take( - continuation: fn() -> Action(e), - desired: Int, - acc: List(e), -) -> List(e) { - case desired > 0 { - True -> - case continuation() { - Continue(element, iterator) -> - do_take(iterator, desired - 1, [element, ..acc]) - Stop -> - acc - |> list.reverse - } - False -> - acc - |> list.reverse +fn do_take(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { + fn() { + case desired > 0 { + False -> Stop + True -> + case continuation() { + Stop -> Stop + Continue(e, next) -> Continue(e, do_take(next, desired - 1)) + } + } } } -/// Evaluates a desired number of elements from an iterator and return them in a -/// list. +/// Creates an iterator that only yields the first `desired` elements. /// -/// If the iterator does not have enough elements all of them are returned. +/// If the iterator does not have enough elements all of them are yielded. /// /// ## Examples /// -/// > [1, 2, 3, 4, 5] |> from_list |> take(up_to: 3) +/// > [1, 2, 3, 4, 5] |> from_list |> take(up_to: 3) |> to_list /// [1, 2, 3] /// -/// > [1, 2] |> from_list |> take(up_to: 3) +/// > [1, 2] |> from_list |> take(up_to: 3) |> to_list /// [1, 2] /// -pub fn take(from iterator: Iterator(e), up_to desired: Int) -> List(e) { +pub fn take(from iterator: Iterator(e), up_to desired: Int) -> Iterator(e) { iterator.continuation - |> do_take(desired, []) + |> do_take(desired) + |> Iterator } fn do_drop(continuation: fn() -> Action(e), desired: Int) -> fn() -> Action(e) { diff --git a/src/gleam/string.gleam b/src/gleam/string.gleam index 4256dd4..7f7653c 100644 --- a/src/gleam/string.gleam +++ b/src/gleam/string.gleam @@ -322,6 +322,7 @@ pub fn concat(strings: List(String)) -> String { pub fn repeat(string: String, times times: Int) -> String { iterator.repeat(string) |> iterator.take(times) + |> iterator.to_list |> concat } diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index b2ca8ac..9250f9c 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -47,6 +47,7 @@ pub fn take_test() { subject |> iterator.from_list |> iterator.take(n) + |> iterator.to_list |> should.equal(list.take(subject, n)) } @@ -173,6 +174,7 @@ pub fn repeat_test() { 1 |> iterator.repeat |> iterator.take(5) + |> iterator.to_list |> should.equal([1, 1, 1, 1, 1]) } @@ -181,16 +183,19 @@ pub fn cycle_test() { |> iterator.from_list |> iterator.cycle |> iterator.take(9) + |> iterator.to_list |> should.equal([1, 2, 3, 1, 2, 3, 1, 2, 3]) } pub fn unfold_test() { iterator.unfold(2, fn(acc) { iterator.Next(acc, acc * 2) }) |> iterator.take(5) + |> iterator.to_list |> should.equal([2, 4, 8, 16, 32]) iterator.unfold(2, fn(_) { iterator.Done }) |> iterator.take(5) + |> iterator.to_list |> should.equal([]) fn(n) { @@ -262,6 +267,7 @@ pub fn iterate_test() { fn(x) { x * 3 } |> iterator.iterate(from: 1) |> iterator.take(5) + |> iterator.to_list |> should.equal([1, 3, 9, 27, 81]) } |