Minimal lazy-iterator helpers (v0.19.0).

Cure comprehensions today are always eager (they lower to :lists.map). Std.Iter ships a tiny iterator shape and two of the most important consumers -- fold and take -- so that programs can express lazy sequences explicitly and consumers can stop early without materialising the tail.

An iterator is a zero-argument lambda returning either Some(%[element, next_iter]) or None(). That shape is close to Elixir's Stream and lets the caller resume after every step.

Examples

use Std.Iter

# Sum of the integers in [1, 10] via the iterator API.
fold(range(1, 10), 0, fn(x) -> fn(acc) -> acc + x)
# => 55
use Std.Iter

# Take at most 3 elements from a potentially infinite iterator.
take(from_list([1, 2, 3, 4, 5]), 3)      # => [1, 2, 3]

Functions

  • # fn __group__() -> Atom

    Group tag consumed by Cure.Stdlib.Preload.

  • # fn empty() -> (Atom) -> Any

    An iterator that is immediately exhausted.

  • # fn fold(it: (Atom) -> Any, acc: T, f: (Any) -> (T) -> T) -> T

    Left fold an iterator. f is a curried function elem -> acc -> acc.

  • # fn from_list(list: List(T)) -> (Atom) -> Any

    An iterator over a list (walks left to right).

  • # fn range(lo: Int, hi: Int) -> (Atom) -> Any

    A bounded integer range iterator (inclusive).

  • # fn take(it: (Atom) -> Any, n: Int) -> List(Any)

    Take at most n values from the iterator as a plain list. Safe to call on infinite iterators.

  • # fn to_list(it: (Atom) -> Any) -> List(Any)

    Materialise an iterator as a list. Non-terminating iterators never return; guard with take/2 when unsure.