Skip to content

Iterator[A: A]

[Source]

Iterators generate a series of values, one value at a time on each call to next().

An Iterator is considered exhausted, once its has_next() method returns false. Thus every call to next() should be preceeded with a call to has_next() to check for exhaustiveness.

Usage

Given the rules for using Iterators mentioned above, basic usage of an iterator looks like this:

while iterator.has_next() do
  let elem = iterator.next()?
  // do something with elem
end

The For-loop provides a more concise way of iteration:

for elem in iterator do
  // do something with elem
end

Iteration using While is more flexible as it allows to continue iterating if a call to next() errors. The For-loop does not allow this.

Implementing Iterators

Iterator implementations need to adhere to the following rules to be considered well-behaved:

  • If the Iterator is exhausted, has_next() needs to return false.
  • Once has_next() returned false it is not allowed to switch back to true (Unless the Iterator supports rewinding)
  • has_next() does not change its returned value if next() has not been called. That means, that between two calls to next() any number of calls to has_next() need to return the same value. (Unless the Iterator supports rewinding)
  • A call to next() erroring does not necessarily denote exhaustiveness.

Example

// Generates values from `from` to 0
class ref Countdown is Iterator[USize]
  var _cur: USize
  var _has_next: Bool = true

  new ref create(from: USize) =>
    _cur = from

  fun ref has_next(): Bool =>
    _has_next

  fun ref next(): USize =>
    let elem = _cur = _cur - 1
    if elem == 0 then
      _has_next = false
    end
    elem
interface ref Iterator[A: A]

Public Functions

has_next

[Source]

Returns true if this Iterator is not yet exhausted. That means that a value returned from a subsequent call to next() is a valid part of this iterator.

Returns false if this Iterator is exhausted.

The behavior of next() after this function returned false is undefined, it might throw an error or return values which are not part of this Iterator.

fun ref has_next()
: Bool val

Returns


next

[Source]

Generate the next value.

This might error, which does not necessarily mean that the Iterator is exhausted.

fun ref next()
: A ?

Returns

  • A ?