diff options
author | drew <drew@drewolson.org> | 2020-11-03 07:22:37 -0600 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2020-11-03 13:25:01 +0000 |
commit | e1dce822e1ff14664a30b429b5e2e2cbf3748221 (patch) | |
tree | 0c940f1d641fac784d7dd120414de29e4b80b2f9 | |
parent | cbac55e668d7fc7df601b604e741b1baa64c7db8 (diff) | |
download | gleam_stdlib-e1dce822e1ff14664a30b429b5e2e2cbf3748221.tar.gz gleam_stdlib-e1dce822e1ff14664a30b429b5e2e2cbf3748221.zip |
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.
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | src/gleam/iterator.gleam | 28 | ||||
-rw-r--r-- | test/gleam/iterator_test.gleam | 26 |
3 files changed, 55 insertions, 2 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 55a19ae..1ccebdd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,8 @@ - The `dynamic` module gains the `option` function. - The `uri` module gains the `percent_encode` and `percent_decode` functions. - The `os` module gains the `erlang_timestamp` function. -- The `iterator` module gains the `append`, `flatten` and `flat_map` functions. +- The `iterator` module gains the `append`, `flatten`, `flat_map` and `step` + functions. ## v0.11.0 - 2020-08-22 diff --git a/src/gleam/iterator.gleam b/src/gleam/iterator.gleam index bfc8455..e75b0a7 100644 --- a/src/gleam/iterator.gleam +++ b/src/gleam/iterator.gleam @@ -168,6 +168,34 @@ pub fn to_list(iterator: Iterator(element)) -> List(element) { |> list.reverse } +/// Eagerly access the first value of an interator, returning a `Next` +/// that contains the first value and the rest of the iterator. +/// +/// If called on an empty iterator, `Done` is returned. +/// +/// ## Examples +/// +/// > assert Next(head, tail) = +/// > [1, 2, 3, 4] +/// > |> from_list +/// > |> step +/// > head +/// 1 +/// > tail |> to_list +/// [2, 3, 4] +/// +/// > [] +/// > |> from_list +/// > |> step +/// Done +/// +pub fn step(iterator: Iterator(e)) -> Step(e, Iterator(e)) { + case iterator.continuation() { + Stop -> Done + Continue(e, a) -> Next(e, Iterator(a)) + } +} + fn do_take( continuation: fn() -> Action(e), desired: Int, diff --git a/test/gleam/iterator_test.gleam b/test/gleam/iterator_test.gleam index acaac81..426c9f7 100644 --- a/test/gleam/iterator_test.gleam +++ b/test/gleam/iterator_test.gleam @@ -1,5 +1,5 @@ import gleam/should -import gleam/iterator +import gleam/iterator.{Done, Next} import gleam/list // a |> from_list |> to_list == a @@ -17,6 +17,30 @@ pub fn to_from_list_test() { test([1, 2, 4, 8]) } +pub fn step_test() { + let test = fn(subject) { + let step = + subject + |> iterator.from_list + |> iterator.step + + case subject { + [] -> + step + |> should.equal(Done) + + [h, ..t] -> + step + |> should.equal(Next(h, iterator.from_list(t))) + } + } + + test([]) + test([1]) + test([1, 2]) + test([1, 2, 3]) +} + // a |> from_list |> take(n) == a |> list.take(_, n) pub fn take_test() { let test = fn(n, subject) { |