aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Daniels <cjdaniels4@gmail.com>2023-03-23 12:59:31 -0400
committerLouis Pilfold <louis@lpil.uk>2023-03-23 19:48:27 +0000
commitb2b07ef0612cc549508b757826d8d143d9587119 (patch)
treec45ae71d2cc53f50afb65360f7d357db65c1d2f1
parent35b5049025d6b09fa5979840b340ba63d5c948d9 (diff)
downloadgleam_stdlib-b2b07ef0612cc549508b757826d8d143d9587119.tar.gz
gleam_stdlib-b2b07ef0612cc549508b757826d8d143d9587119.zip
Make iterator.any/all TCO eligible in JavaScript
Fixes #427
-rw-r--r--src/gleam/iterator.gleam16
-rw-r--r--test/gleam/iterator_test.gleam12
2 files changed, 24 insertions, 4 deletions
diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam
index 89d50a8..1486ae3 100644
--- a/src/gleam/iterator.gleam
+++ b/src/gleam/iterator.gleam
@@ -995,7 +995,11 @@ fn do_any(
) -> Bool {
case continuation() {
Stop -> False
- Continue(e, next) -> predicate(e) || do_any(next, predicate)
+ Continue(e, next) ->
+ case predicate(e) {
+ True -> True
+ False -> do_any(next, predicate)
+ }
}
}
@@ -1037,7 +1041,11 @@ fn do_all(
) -> Bool {
case continuation() {
Stop -> True
- Continue(e, next) -> predicate(e) && do_all(next, predicate)
+ Continue(e, next) ->
+ case predicate(e) {
+ True -> do_all(next, predicate)
+ False -> False
+ }
}
}
@@ -1391,10 +1399,10 @@ fn do_length(over continuation: fn() -> Action(e), with length: Int) -> Int {
/// Counts the number of elements in the given iterator.
///
/// This function has to traverse the entire iterator to count its elements,
-/// so it runs in linear time.
+/// so it runs in linear time.
///
/// ## Examples
-///
+///
/// ```gleam
/// > empty() |> length
/// 0
diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam
index 9c98c9d..81c790e 100644
--- a/test/gleam/iterator_test.gleam
+++ b/test/gleam/iterator_test.gleam
@@ -406,6 +406,12 @@ pub fn any_test() {
iterator.from_list([1, 3, 5, 7, 9])
|> iterator.any(satisfying: fn(n) { n % 2 == 0 })
|> should.be_false
+
+ // TCO test
+ iterator.repeat(1)
+ |> iterator.take(1_000_000)
+ |> iterator.any(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_false
}
pub fn all_test() {
@@ -420,6 +426,12 @@ pub fn all_test() {
iterator.from_list([2, 4, 5, 8])
|> iterator.all(satisfying: fn(n) { n % 2 == 0 })
|> should.be_false
+
+ // TCO test
+ iterator.repeat(0)
+ |> iterator.take(1_000_000)
+ |> iterator.all(satisfying: fn(n) { n % 2 == 0 })
+ |> should.be_true
}
pub fn group_test() {