Std.Iter
View source →Lazy iterators.
Cure comprehensions and Std.List are eager: every step
materialises a new cons list. Std.Iter is the lazy half of the
collections story. An iterator is an inductive wrapper around a
step function. Each step returns either Some(Yield(element, next))
or None(), so the element and continuation stay typed without
falling back to Any.
The lazy idiom
The recommended way to spell a lazy pipeline is to mark the entry
point with lazy/1 and let the rest of the chain stay in
Std.Iter:
use Std.Iter
# Squares of the first five even integers in [1, 10].
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|> lazy
|> filter(fn(x) -> x % 2 == 0)
|> map(fn(x) -> x * x)
|> take(5)
# => [4, 16, 36, 64, 100]
Nothing materialises until the terminal take/2 (which returns a
plain list). For an open-ended chain, end with to_list/1 --
guard infinite producers with take/2 or take_while/2 first.
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
# First five Fibonacci numbers from an infinite producer.
let pair_step = fn(p) ->
match p
%[a, b] -> Some(Emit(a, %[b, a + b]))
unfold(%[0, 1], pair_step) |> take(5)
# => [0, 1, 1, 2, 3]
Types
-
type StepToken -
type Iter = Iter -
type IterStep = Yield -
type UnfoldStep = Emit -
type EachDone
Functions
-
# fn all(it: Iter(t), pred: Function(t, Bool)) -> Bool
truewhen every element satisfiespred(vacuously true for the empty iterator). Stops at the first miss. -
# fn any(it: Iter(t), pred: Function(t, Bool)) -> Bool
truewhen at least one element satisfiespred. Stops at the first hit. -
# fn concat(a: Iter(t), b: Iter(t)) -> Iter(t)
Concatenate two iterators. Stepping
bis deferred untilais exhausted. -
# fn count(it: Iter(t), pred: Function(t, Bool)) -> Int
Count elements satisfying
pred. Tail-recursive. -
# fn cycle(list: List(t)) -> Iter(t)
Infinite iterator that walks
listrepeatedly. An empty input collapses toempty/0so consumers terminate. -
# fn drop(it: Iter(t), n: Int) -> Iter(t)
Skip the first
nelements. Negative or zeronis a no-op. -
# fn drop_while(it: Iter(t), pred: Function(t, Bool)) -> Iter(t)
Skip elements while
predholds, then yield the rest unchanged. -
# fn each(it: Iter(t), f: Function(t, u)) -> EachDone
Apply
fto every element for its side effects. ReturnsDoneonce the iterator is exhausted. -
# fn empty() -> Iter(t)
An iterator that is immediately exhausted.
-
# fn filter(it: Iter(t), pred: Function(t, Bool)) -> Iter(t)
Keep elements of
itfor whichpred(elem)istrue. -
# fn find(it: Iter(t), pred: Function(t, Bool), default: t) -> t
First element satisfying
pred; returnsdefaultwhen nothing matches. Stops at the first hit. -
# fn flat_map(it: Iter(t), f: Function(t, Iter(u))) -> Iter(u)
Map
foveritand flatten one level of nesting;freturns an iterator per element. -
# fn fold(it: Iter(t), acc: u, f: Function(t, Function(u, u))) -> u
Left fold an iterator.
fis a curried functionelem -> acc -> acc. -
# fn from_list(list: List(t)) -> Iter(t)
An iterator over a list (walks left to right).
-
# fn intersperse(it: Iter(t), sep: t) -> Iter(t)
Insert
sepbetween consecutive elements ofit. Empty and single-element iterators are passed through unchanged. -
# fn iterate(x0: t, f: Function(t, t)) -> Iter(t)
Infinite iterator:
x0, f(x0), f(f(x0)), .... Always pair with a slicer such astake/2ortake_while/2before forcing. -
# fn lazy(list: List(t)) -> Iter(t)
Bridge for the lazy-pipeline idiom:
xs |> lazy |> map(...) |> .... Identical tofrom_list/1; the alternate name documents intent at the call site. -
# fn map(it: Iter(t), f: Function(t, u)) -> Iter(u)
Map
fover every element ofit, on demand. -
# fn range(lo: Int, hi: Int) -> Iter(Int)
A bounded integer range iterator (inclusive).
-
# fn repeat(x: t) -> Iter(t)
Infinite iterator that yields
xforever. -
# fn take(it: Iter(t), n: Int) -> List(t)
Take at most
nvalues from the iterator as a plain list. Safe to call on infinite iterators. -
# fn take_while(it: Iter(t), pred: Function(t, Bool)) -> Iter(t)
Lazy prefix: keep elements while
predholds, then terminate. -
# fn to_list(it: Iter(t)) -> List(t)
Materialise an iterator as a list. Non-terminating iterators never return; guard with
take/2when unsure. -
# fn unfold(seed: s, f: Function(s, Option(UnfoldStep(t, s)))) -> Iter(t)
Stream-style unfold.
f(seed)returns eitherSome(Emit(value, next_seed))to emitvalueand continue, orNone()to terminate. -
# fn zip_with(a: Iter(t), b: Iter(u), f: Function(t, Function(u, v))) -> Iter(v)
Combine two iterators element-wise using a curried
f. Stops at the shorter iterator.fisa -> b -> c.