aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gleam/iterator.gleam43
-rw-r--r--src/gleam/string.gleam1
-rw-r--r--test/gleam/iterator_test.gleam6
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])
}