Skip to content

Commit e1dce82

Browse files
drewolsonlpil
authored andcommitted
Add step eliminator for iterators
The `step` function allows eager access to the first item in the iterator, but does not force the rest of the iterator.
1 parent cbac55e commit e1dce82

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
- The `dynamic` module gains the `option` function.
1111
- The `uri` module gains the `percent_encode` and `percent_decode` functions.
1212
- The `os` module gains the `erlang_timestamp` function.
13-
- The `iterator` module gains the `append`, `flatten` and `flat_map` functions.
13+
- The `iterator` module gains the `append`, `flatten`, `flat_map` and `step`
14+
functions.
1415

1516
## v0.11.0 - 2020-08-22
1617

src/gleam/iterator.gleam

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,34 @@ pub fn to_list(iterator: Iterator(element)) -> List(element) {
168168
|> list.reverse
169169
}
170170

171+
/// Eagerly access the first value of an interator, returning a `Next`
172+
/// that contains the first value and the rest of the iterator.
173+
///
174+
/// If called on an empty iterator, `Done` is returned.
175+
///
176+
/// ## Examples
177+
///
178+
/// > assert Next(head, tail) =
179+
/// > [1, 2, 3, 4]
180+
/// > |> from_list
181+
/// > |> step
182+
/// > head
183+
/// 1
184+
/// > tail |> to_list
185+
/// [2, 3, 4]
186+
///
187+
/// > []
188+
/// > |> from_list
189+
/// > |> step
190+
/// Done
191+
///
192+
pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) {
193+
case iterator.continuation() {
194+
Stop -> Done
195+
Continue(e, a) -> Next(e, Iterator(a))
196+
}
197+
}
198+
171199
fn do_take(
172200
continuation: fn() -> Action(e),
173201
desired: Int,

test/gleam/iterator_test.gleam

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import gleam/should
2-
import gleam/iterator
2+
import gleam/iterator.{Done, Next}
33
import gleam/list
44

55
// a |> from_list |> to_list == a
@@ -17,6 +17,30 @@ pub fn to_from_list_test() {
1717
test([1, 2, 4, 8])
1818
}
1919

20+
pub fn step_test() {
21+
let test = fn(subject) {
22+
let step =
23+
subject
24+
|> iterator.from_list
25+
|> iterator.step
26+
27+
case subject {
28+
[] ->
29+
step
30+
|> should.equal(Done)
31+
32+
[h, ..t] ->
33+
step
34+
|> should.equal(Next(h, iterator.from_list(t)))
35+
}
36+
}
37+
38+
test([])
39+
test([1])
40+
test([1, 2])
41+
test([1, 2, 3])
42+
}
43+
2044
// a |> from_list |> take(n) == a |> list.take(_, n)
2145
pub fn take_test() {
2246
let test = fn(n, subject) {

0 commit comments

Comments
 (0)