diff options
author | Louis Pilfold <louis@lpil.uk> | 2022-07-25 22:16:59 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2022-07-25 22:17:05 +0100 |
commit | f4ff3b795e105e216c1a3b4d9b350f06533e1927 (patch) | |
tree | a476802d119dd7b0de695aaaab351cfd1f5d5367 | |
parent | 472fbe4fb741f274be1054276065a4b06b84f92a (diff) | |
download | gleam_stdlib-f4ff3b795e105e216c1a3b4d9b350f06533e1927.tar.gz gleam_stdlib-f4ff3b795e105e216c1a3b4d9b350f06533e1927.zip |
Make list.range tail recursive
-rw-r--r-- | src/gleam/list.gleam | 10 | ||||
-rw-r--r-- | test/gleam/list_test.gleam | 3 |
2 files changed, 10 insertions, 3 deletions
diff --git a/src/gleam/list.gleam b/src/gleam/list.gleam index c787935..1a9d5ce 100644 --- a/src/gleam/list.gleam +++ b/src/gleam/list.gleam @@ -1048,10 +1048,14 @@ pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) { /// ``` /// pub fn range(from start: Int, to stop: Int) -> List(Int) { + tail_recursive_range(start, stop, []) +} + +fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) { case int.compare(start, stop) { - order.Eq -> [] - order.Gt -> [start, ..range(start - 1, stop)] - order.Lt -> [start, ..range(start + 1, stop)] + order.Eq -> reverse(acc) + order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc]) + order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc]) } } diff --git a/test/gleam/list_test.gleam b/test/gleam/list_test.gleam index 971a5f1..566aa94 100644 --- a/test/gleam/list_test.gleam +++ b/test/gleam/list_test.gleam @@ -488,6 +488,9 @@ pub fn range_test() { list.range(1, -5) |> should.equal([1, 0, -1, -2, -3, -4]) + + // This should not overflow the stack + list.range(1, 100_000) } pub fn repeat_test() { |