Skip to content

Commit 4b3b5d9

Browse files
TanklesXLlpil
authored andcommitted
inclusive list.range and iterator.range
1 parent 2d991bd commit 4b3b5d9

File tree

5 files changed

+47
-33
lines changed

5 files changed

+47
-33
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
ranges when compiled to JavaScript.
99
- Fixed a bug where the `list` module's `contains`, `any`, and `all` could
1010
exhaust the stack when compiling to JavaScript.
11+
- `list.range` and `iterator.range` return values are now inclusive of both start and end bounds.
1112

1213
## v0.22.1 - 2022-06-27
1314

src/gleam/iterator.gleam

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import gleam/int
12
import gleam/list
23
import gleam/map.{Map}
34
import gleam/option.{None, Option, Some}
5+
import gleam/order
46

57
// Internal private representation of an Iterator
68
type Action(element) {
@@ -447,29 +449,40 @@ pub fn cycle(iterator: Iterator(a)) -> Iterator(a) {
447449
///
448450
/// ```gleam
449451
/// > range(from: 1, to: 5) |> to_list
450-
/// [1, 2, 3, 4]
452+
/// [1, 2, 3, 4, 5]
451453
///
452454
/// > range(from: 1, to: -2) |> to_list
453-
/// [1, 0, -1]
455+
/// [1, 0, -1, -2]
454456
///
455457
/// > range(from: 0, to: 0) |> to_list
456-
/// []
458+
/// [0]
457459
/// ```
458460
///
459461
pub fn range(from start: Int, to stop: Int) -> Iterator(Int) {
460-
let increment = case start < stop {
461-
True -> 1
462-
False -> -1
463-
}
464-
465-
let next_step = fn(current) {
466-
case current == stop {
467-
True -> Done
468-
False -> Next(current, current + increment)
469-
}
462+
case int.compare(start, stop) {
463+
order.Eq -> once(fn() { start })
464+
order.Gt ->
465+
unfold(
466+
from: start,
467+
with: fn(current) {
468+
case current < stop {
469+
False -> Next(current, current - 1)
470+
True -> Done
471+
}
472+
},
473+
)
474+
475+
order.Lt ->
476+
unfold(
477+
from: start,
478+
with: fn(current) {
479+
case current > stop {
480+
False -> Next(current, current + 1)
481+
True -> Done
482+
}
483+
},
484+
)
470485
}
471-
472-
unfold(start, next_step)
473486
}
474487

475488
fn do_find(continuation: fn() -> Action(a), f: fn(a) -> Bool) -> Result(a, Nil) {

src/gleam/list.gleam

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,13 +1038,13 @@ pub fn sort(list: List(a), by compare: fn(a, a) -> Order) -> List(a) {
10381038
///
10391039
/// ```gleam
10401040
/// > range(0, 0)
1041-
/// []
1041+
/// [0]
10421042
///
10431043
/// > range(0, 5)
1044-
/// [0, 1, 2, 3, 4]
1044+
/// [0, 1, 2, 3, 4, 5]
10451045
///
10461046
/// > range(1, -5)
1047-
/// [1, 0, -1, -2, -3, -4]
1047+
/// [1, 0, -1, -2, -3, -4, -5]
10481048
/// ```
10491049
///
10501050
pub fn range(from start: Int, to stop: Int) -> List(Int) {
@@ -1053,7 +1053,7 @@ pub fn range(from start: Int, to stop: Int) -> List(Int) {
10531053

10541054
fn tail_recursive_range(start: Int, stop: Int, acc: List(Int)) -> List(Int) {
10551055
case int.compare(start, stop) {
1056-
order.Eq -> reverse(acc)
1056+
order.Eq -> reverse([stop, ..acc])
10571057
order.Gt -> tail_recursive_range(start - 1, stop, [start, ..acc])
10581058
order.Lt -> tail_recursive_range(start + 1, stop, [start, ..acc])
10591059
}

test/gleam/iterator_test.gleam

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,19 +222,19 @@ pub fn range_test() {
222222
|> should.equal(expected)
223223
}
224224

225-
test(0, 0, [])
226-
test(1, 1, [])
227-
test(-1, -1, [])
228-
test(0, 1, [0])
229-
test(0, 5, [0, 1, 2, 3, 4])
230-
test(1, -5, [1, 0, -1, -2, -3, -4])
225+
test(0, 0, [0])
226+
test(1, 1, [1])
227+
test(-1, -1, [-1])
228+
test(0, 1, [0, 1])
229+
test(0, 5, [0, 1, 2, 3, 4, 5])
230+
test(1, -5, [1, 0, -1, -2, -3, -4, -5])
231231
}
232232

233233
pub fn drop_test() {
234234
iterator.range(0, 10)
235235
|> iterator.drop(5)
236236
|> iterator.to_list
237-
|> should.equal([5, 6, 7, 8, 9])
237+
|> should.equal([5, 6, 7, 8, 9, 10])
238238
}
239239

240240
type Cat {
@@ -392,7 +392,7 @@ pub fn last_test() {
392392

393393
iterator.range(1, 10)
394394
|> iterator.last
395-
|> should.equal(Ok(9))
395+
|> should.equal(Ok(10))
396396
}
397397

398398
pub fn empty_test() {

test/gleam/list_test.gleam

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -472,22 +472,22 @@ pub fn index_map_test() {
472472

473473
pub fn range_test() {
474474
list.range(0, 0)
475-
|> should.equal([])
475+
|> should.equal([0])
476476

477477
list.range(1, 1)
478-
|> should.equal([])
478+
|> should.equal([1])
479479

480480
list.range(-1, -1)
481-
|> should.equal([])
481+
|> should.equal([-1])
482482

483483
list.range(0, 1)
484-
|> should.equal([0])
484+
|> should.equal([0, 1])
485485

486486
list.range(0, 5)
487-
|> should.equal([0, 1, 2, 3, 4])
487+
|> should.equal([0, 1, 2, 3, 4, 5])
488488

489489
list.range(1, -5)
490-
|> should.equal([1, 0, -1, -2, -3, -4])
490+
|> should.equal([1, 0, -1, -2, -3, -4, -5])
491491

492492
// This should not overflow the stack
493493
list.range(1, 100_000)

0 commit comments

Comments
 (0)