API reference

fp.iteration

fp.iteration provides lazy mapping, filtering and scans, together with folds, reductions and searches over native iterators and owned collections. The iteration tutorial follows values through a lazy chain and shows how a terminal operation consumes them.

Lazy adapters, folds, reductions and terminal operations over native iterators.

Every operation consumes a source: a native iterator, used as it is and never restarted, or an owned collection (any IterableOwned, such as List, Set or Dict), consumed as iter(values^) would. Pass values^ to consume a collection, or iter(values) to borrow it. Standard adapters (chain, zip, enumerate, take, drop, peekable, ...) come from std.iter and std.itertools and combine freely with these.

iterated(source) adds consuming method syntax to the same native iterators: iterated(values^).map(f).filter(p).to_list(). Its Iter wrapper implements Iterator and IterableOwned, so standard consuming adapters accept it directly. Wrap a standard adapter's result with iterated to continue chaining. to_list() and collect_list() are alias methods for the free collect_list. Named chains are consumed explicitly, as in stream^.to_list().

Lazy adapters (map, filter, filter_map, flatten, flat_map, scan_left) are native iterators whose advancement raises only StopIteration:

  • Construction is inert: nothing is pulled and no callback runs until the first next.
  • They are fused: after a source reports exhaustion it is never pulled again.
  • There is no lookahead: each output pulls only what it needs.
  • Abandoning one destroys its owned state without evaluating the rest.

Lazy callbacks do not raise, because a native iterator can raise only StopIteration; to carry a domain failure, yield Result elements and aggregate them with collect_results. A callback is a plain function, a capturing closure or, for map, filter_map, flat_map and scan_left, a shared-receiver Unary/Binary value such as a Partial. Move a closure that owns non-trivial state in with callback^. Owners of borrowed captures must stay alive and unmoved while the adapter is used. A generic function that returns an adapter names its type with MapIterator, ScanIterator, FilterIterator, FilterMapIterator or FlatMapIterator, declares I: Iterator and where I.Element == T, and builds the value through the function; the types add no storage, and the source origin stays part of the type.

Folds and terminals (fold_left, fold_until, reduce, reduce_optional, collect_list, find, any, all) run at once:

Operation Non-empty input Empty input
fold_left(step, initial, source) n calls of step(var A, var T) -> A, in order initial, no calls
reduce(step, source, initial=value) The same as fold_left initial, no calls
reduce(step, source) The first element seeds the accumulator; n - 1 calls Raises EmptyReductionError
reduce_optional(step, source) As above, wrapped in Optional None
fold_until(step, initial, source) Each call returns ControlFlow[B, A]; Break(b) returns at once Continue(initial)
collect_list(source) A List of every element, moved An empty list
find(p, source) The first accepted element None
any(p, source) / all(p, source) Stops at the first decisive element False / True

Steps are never reassociated. Pure and raising callbacks have separate overloads, and a callback's error type propagates unchanged; a callback that raises StopIteration fails as a callback, never as exhaustion. The first decisive result or failure stops without another pull. On failure, native cleanup destroys the source, the current accumulator and the pulled element; side effects are not rolled back. Every operation makes O(n) callback calls, or fewer after an early stop, with constant extra state.

A generic function forwards to these with the native callback constraint and where I.Element == T. A raising wrapper passes E=E at every call and must not read F.E or F.T from a callback type: Mojo 1.1 does not reliably expose those attributes through a precompiled package. Keep the parameter names shown in the tutorial's generic examples; on Mojo 1.1 some renamings lose callback conformance.

Summary

Name Kind Summary
all function Whether predicate accepts every element; stops at the first rejected one.
any function Whether predicate accepts some element; stops at the first accepted one.
collect_list function Collect every element of a source into a List, in order.
filter function Lazily keep the elements predicate accepts.
filter_map function Lazily apply function and keep the present results.
find function Return the first element predicate accepts, without pulling another.
flat_map function Lazily apply function and concatenate the inner sources it returns: flatten(map(function, source)).
flatten function Lazily concatenate the inner sources a source yields.
fold_left function Fold a source from the left: step(... step(step(initial, x0), x1) ..., xn).
fold_until function Fold until a step returns Break, without pulling another element.
iterated function Start a consuming method chain over an iterator or owned collection.
map function Lazily apply function to each element: function(x0), function(x1), ....
reduce function Reduce a source from an initial value: the same as fold_left.
reduce_optional function Reduce a source with its first element as the accumulator; empty input gives None.
scan_left function Lazily yield initial and then the accumulator after each step: n + 1 values for n elements.
EmptyReductionError struct The error of reduce without an initial value on an empty source.
Iter struct A native iterator with consuming transformation and terminal methods.
ReductionStepError struct A reduction step's error, kept distinct from empty input.
FilterIterator alias The type filter returns, for a generic function's return annotation.
FilterMapIterator alias The type filter_map returns, for a generic function's return annotation.
FlatMapIterator alias The type flat_map returns, for a generic function's return annotation.
MapIterator alias The type map returns, for a generic function's return annotation.
ReductionError alias The error of a raising reduce without an initial value: empty input, or the step's error.
ScanIterator alias The type scan_left returns, for a generic function's return annotation.

Functions

all

Source: fp/iteration/adapters.mojo

def all[T, I, //, F: def(T) -> Bool](
    predicate: F,
    var source: I,
) -> Bool where _Source[I].Element == T

Whether predicate accepts every element; stops at the first rejected one.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(T) -> Bool): The predicate's type: a plain function or a closure.

Arguments

  • predicate (F): The predicate, borrowed; it borrows each candidate.
  • source (var I): The source, consumed.

Returns

Bool: False at the first rejected element; True for an empty source.

2 more overloads

Whether a raising predicate accepts every element; its error stops the search.

def all[T, I, E, //, F: def(T) raises E -> Bool](
    predicate: F,
    var source: I,
) raises E -> Bool where _Source[I].Element == T

Whether a `BorrowCallable` predicate accepts every element.

def all[I, C: BorrowCallable](
    predicate: C,
    var source: I,
) raises C.Failure -> Bool where conforms_to(_Source[I].Element, Movable & Deinitable) and C.Payload == _Source[I].Element and C.Result == Bool

any

Source: fp/iteration/adapters.mojo

def any[T, I, //, F: def(T) -> Bool](
    predicate: F,
    var source: I,
) -> Bool where _Source[I].Element == T

Whether predicate accepts some element; stops at the first accepted one.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(T) -> Bool): The predicate's type: a plain function or a closure.

Arguments

  • predicate (F): The predicate, borrowed; it borrows each candidate.
  • source (var I): The source, consumed.

Returns

Bool: True at the first accepted element; False for an empty source.

2 more overloads

Whether a raising predicate accepts some element; its error stops the search.

def any[T, I, E, //, F: def(T) raises E -> Bool](
    predicate: F,
    var source: I,
) raises E -> Bool where _Source[I].Element == T

Whether a `BorrowCallable` predicate accepts some element.

def any[I, C: BorrowCallable](
    predicate: C,
    var source: I,
) raises C.Failure -> Bool where conforms_to(_Source[I].Element, Movable & Deinitable) and C.Payload == _Source[I].Element and C.Result == Bool

collect_list

Source: fp/iteration/adapters.mojo

def collect_list[T, I](var source: I) -> List[T] where _Source[I].Element == T

Collect every element of a source into a List, in order.

Parameters

  • T (Movable & Deinitable): The element type.
  • I (Movable & Deinitable): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • source (var I): The source, consumed.

Returns

List[T]: A List of the elements, moved in; empty for an empty source.

filter

Source: fp/iteration/adapters.mojo

def filter[T, I, //](
    function: def(T) thin -> Bool,
    var source: I,
) -> _Filter[T, _Source[I]] where _Source[I].Element == T

Lazily keep the elements predicate accepts.

The predicate borrows each candidate, and the original element is yielded unchanged. Each output pulls until a candidate is accepted.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • function (def(T) thin -> Bool): The predicate, a plain function, stored.
  • source (var I): The source, consumed.

Returns

A FilterIterator, a native iterator of the accepted elements.

2 more overloads

Lazily keep the elements a closure predicate accepts.

def filter[T, I, //, F: _LazyPredicate[T]](
    var function: F,
    var source: I,
) -> _Filter[T, _Source[I], F] where _Source[I].Element == T

Lazily keep the elements a `BorrowCallable` predicate accepts.

def filter[I, C: BorrowCallable](
    var predicate: C,
    var source: I,
) -> _Filter[_Source[I].Element, _Source[I], C] where conforms_to(_Source[I].Element, Movable & Deinitable) and C.Payload == _Source[I].Element and C.Result == Bool and C.Failure == Never

filter_map

Source: fp/iteration/adapters.mojo

def filter_map[T, U, I, //](
    function: def(var T) thin -> Optional[U],
    var source: I,
) -> _FilterMap[T, U, _Source[I]] where _Source[I].Element == T

Lazily apply function and keep the present results.

Each element is moved into the function. Only None is skipped: a present Result.Err is an ordinary output.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • U (Movable & Deinitable, inferred): The type of a present result.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • function (def(var T) thin -> Optional[U]): A plain function returning Optional[U], stored.
  • source (var I): The source, consumed.

Returns

A FilterMapIterator, a native iterator of the present results.

2 more overloads

Lazily apply a closure returning `Optional[U]` and keep the present results.

def filter_map[T, U, I, //, F: _LazyOptional[T, U]](
    var function: F,
    var source: I,
) -> _FilterMap[T, U, _Source[I], F] where _Source[I].Element == T

Lazily apply a library `Unary` value returning `Optional[U]`; name `U` explicitly.

def filter_map[U, I, F: Unary](
    var function: F,
    var source: I,
) -> _FilterMap[F.Arg, U, _Source[I], F] where _Source[I].Element == F.Arg and F.Out == Optional[U] and F.Error == Never

find

Source: fp/iteration/adapters.mojo

def find[T, I, //, F: def(T) -> Bool](
    predicate: F,
    var source: I,
) -> Optional[T] where _Source[I].Element == T

Return the first element predicate accepts, without pulling another.

The predicate borrows each candidate; the accepted element is returned as it is, and rejected ones are destroyed.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(T) -> Bool): The predicate's type: a plain function or a closure.

Arguments

  • predicate (F): The predicate, borrowed.
  • source (var I): The source, consumed.

Returns

Optional[T]: The first accepted element, or None when there is none.

2 more overloads

Return the first accepted element with a raising predicate; its error stops the search.

def find[T, I, E, //, F: def(T) raises E -> Bool](
    predicate: F,
    var source: I,
) raises E -> Optional[T] where _Source[I].Element == T

Return the first element a `BorrowCallable` predicate accepts.

def find[I, C: BorrowCallable](
    predicate: C,
    var source: I,
) raises C.Failure -> Optional[_Source[I].Element] where conforms_to(_Source[I].Element, Movable & Deinitable) and C.Payload == _Source[I].Element and C.Result == Bool

flat_map

Source: fp/iteration/adapters.mojo

def flat_map[T, S, I](
    function: def(var T) thin -> S,
    var source: I,
) -> _Flatten[_Map[T, S, _Source[I]], S] where _Source[I].Element == T

Lazily apply function and concatenate the inner sources it returns: flatten(map(function, source)).

The returned inner iterator or iterable is kept until it is exhausted or the adapter is abandoned.

Parameters

  • T (Movable & Deinitable): The element type.
  • S (Movable & Deinitable): The returned inner source's type: a native iterator or an owned iterable.
  • I (Movable & Deinitable): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • function (def(var T) thin -> S): A plain function, stored.
  • source (var I): The source, consumed.

Returns

A FlatMapIterator, a native iterator of the inner elements.

2 more overloads

Lazily apply a closure and concatenate the inner sources it returns.

def flat_map[T, U, I, //, F: _LazyUnary[T, U]](
    var function: F,
    var source: I,
) -> _Flatten[_Map[T, U, _Source[I], F], U] where _Source[I].Element == T

Lazily apply a library `Unary` value and concatenate the inner sources it returns.

def flat_map[I, F: Unary](
    var function: F,
    var source: I,
) -> _Flatten[_Map[F.Arg, F.Out, _Source[I], F], F.Out] where _Source[I].Element == F.Arg and F.Error == Never

flatten

Source: fp/iteration/adapters.mojo

def flatten[I, S](
    var source: I,
) -> _Flatten[_Source[I], S] where _Source[I].Element == S

Lazily concatenate the inner sources a source yields.

Each inner source, a native iterator or an owned iterable, is exhausted before the next outer element is pulled, and empty inner sources are skipped. An inner iterator may borrow an external owner, which must stay alive.

Parameters

  • I (Movable & Deinitable): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • S (Movable & Deinitable): The inner source's type.

Arguments

  • source (var I): The source of inner sources, consumed.

Returns

A native iterator of the inner elements, in order.

fold_left

Source: fp/iteration/folds.mojo

def fold_left[A, T, I, //, F: def(var A, var T) -> A](
    step: F,
    var initial: A,
    var iterator: I,
) -> A where _Source[I].Element == T

Fold a source from the left: step(... step(step(initial, x0), x1) ..., xn).

Each element is moved into step with the accumulator, in order, and the steps are never reassociated. The accumulator and element types may differ; scalars, SIMD values (whose lanes are never reduced implicitly) and any other accumulator work alike. Empty input returns initial without a call.

Parameters

  • A (Movable & Deinitable, inferred): The accumulator type.
  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(var A, var T) -> A): The step's type: a plain function or a closure.

Arguments

  • step (F): The step, borrowed; it is called once per element.
  • initial (var A): The first accumulator, consumed.
  • iterator (var I): The source, consumed.

Returns

A: The final accumulator.

2 more overloads

Fold with a raising step; its error stops the fold with its own type.

def fold_left[A, T, I, E: AnyType, //, F: def(var A, var T) raises E -> A](
    step: F,
    var initial: A,
    var iterator: I,
) raises E -> A where _Source[I].Element == T

Fold with a library `Binary` step, such as a partial with two remaining arguments.

def fold_left[A, I, F: Binary](
    step: F,
    var initial: A,
    var iterator: I,
) raises F.Error -> A where F.First == A and F.Second == _Source[I].Element and F.Out == A

fold_until

Source: fp/iteration/folds.mojo

def fold_until[A, B, T, I, //, F: def(var A, var T) -> ControlFlow[B, A]](
    step: F,
    var initial: A,
    var iterator: I,
) -> ControlFlow[B, A] where _Source[I].Element == T

Fold until a step returns Break, without pulling another element.

Each step returns Continue(accumulator) to go on or Break(value) to stop at once; the element that caused the break has been consumed. Exhaustion returns Continue with the last accumulator, or initial for empty input.

Parameters

  • A (Movable & Deinitable, inferred): The accumulator type.
  • B (Movable & Deinitable, inferred): The type of the value a step stops with.
  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(var A, var T) -> ControlFlow[B, A]): The step's type: a plain function or a closure returning ControlFlow[B, A].

Arguments

  • step (F): The step, borrowed.
  • initial (var A): The first accumulator, consumed.
  • iterator (var I): The source, consumed.

Returns

ControlFlow[B, A]: The first Break, or Continue with the final accumulator.

2 more overloads

Fold until `Break` with a raising step; its error is a separate outcome from `Break`.

def fold_until[
    A, B, T, I, E, //, F: def(var A, var T) raises E -> ControlFlow[B, A],
](
    step: F,
    var initial: A,
    var iterator: I,
) raises E -> ControlFlow[B, A] where _Source[I].Element == T

Fold until `Break` with a library `Binary` step.

def fold_until[B, A, I, F: Binary](
    step: F,
    var initial: A,
    var iterator: I,
) raises F.Error -> ControlFlow[B, A] where F.First == A and F.Second == _Source[I].Element and F.Out == ControlFlow[B, A]

iterated

Source: fp/iteration/chaining.mojo

def iterated[S](var source: S) -> Iter[_Source[S]]

Start a consuming method chain over an iterator or owned collection.

An iterator keeps its current position. An owned collection is consumed through its native owned iterator. Pass iter(values) to borrow a collection, keeping the owner alive and unmoved while the chain is used. Construction does not pull any elements or run callbacks.

Parameters

  • S (Movable & Deinitable): A native iterator or an IterableOwned collection.

Arguments

  • source (var S): The source, consumed.

Returns

Iter[...]: A native Iterator and IterableOwned wrapper with chaining methods.

map

Source: fp/iteration/adapters.mojo

def map[T, U, I, //](
    function: def(var T) thin -> U,
    var source: I,
) -> _Map[T, U, _Source[I]] where _Source[I].Element == T

Lazily apply function to each element: function(x0), function(x1), ....

Each element is moved into the function, so move-only elements and results work. Nothing is pulled until the first next, and each output pulls one element.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • U (Movable & Deinitable, inferred): The result type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • function (def(var T) thin -> U): A plain function, stored.
  • source (var I): The source, consumed.

Returns

A MapIterator, a native iterator of the results.

2 more overloads

Lazily apply a closure; move one that owns non-trivial state in with `function^`.

def map[T, U, I, //, F: _LazyUnary[T, U]](
    var function: F,
    var source: I,
) -> _Map[T, U, _Source[I], F] where _Source[I].Element == T

Lazily apply a library `Unary` value, such as a partial or a composition.

def map[I, F: Unary](
    var function: F,
    var source: I,
) -> _Map[F.Arg, F.Out, _Source[I], F] where _Source[I].Element == F.Arg and F.Error == Never

reduce

Source: fp/iteration/folds.mojo

def reduce[A, T, I, //, F: def(var A, var T) -> A](
    step: F,
    var iterator: I,
    *,
    var initial: A,
) -> A where _Source[I].Element == T

Reduce a source from an initial value: the same as fold_left.

Parameters

  • A (Movable & Deinitable, inferred): The accumulator type.
  • T (Movable & Deinitable, inferred): The element type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(var A, var T) -> A): The step's type: a plain function or a closure.

Arguments

  • step (F): The step, borrowed; it is called once per element.
  • iterator (var I): The source, consumed.
  • initial (var A): The first accumulator, consumed; returned for empty input.

Returns

A: The final accumulator.

def reduce[T, I, //, F: def(var T, var T) -> T](
    step: F,
    var iterator: I,
) raises EmptyReductionError -> T where _Source[I].Element == T

Reduce a source with its first element as the accumulator.

Parameters

  • T (Movable & Deinitable, inferred): The element and accumulator type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(var T, var T) -> T): The step's type: a plain function or a closure.

Arguments

  • step (F): The step, borrowed; it is called once per element after the first.
  • iterator (var I): The source, consumed.

Returns

T: The final accumulator.

Raises

EmptyReductionError: EmptyReductionError when the source is empty.

def reduce[T, I, E, //, F: def(var T, var T) raises E -> T](
    step: F,
    var iterator: I,
) raises ReductionError[E] -> T where _Source[I].Element == T

Reduce with a raising step and no initial value.

Empty input and a step's error are two different failures, so they raise two alternatives of one Variant.

Parameters

  • T (Movable & Deinitable, inferred): The element and accumulator type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • E (Movable & Deinitable, inferred): The step's error type.
  • F (def(var T, var T) raises E -> T): The step's type: a plain function or a closure that raises E.

Arguments

  • step (F): The step, borrowed; it is called once per element after the first.
  • iterator (var I): The source, consumed.

Returns

T: The final accumulator.

Raises

ReductionError[E]: ReductionError[E]: EmptyReductionError for an empty source, or ReductionStepError[E] holding the step's error.

3 more overloads

Reduce from an initial value with a raising step; its error is kept.

def reduce[A, T, I, E, //, F: def(var A, var T) raises E -> A](
    step: F,
    var iterator: I,
    *,
    var initial: A,
) raises E -> A where _Source[I].Element == T

Reduce from an initial value with a library `Binary` step.

def reduce[A, I, F: Binary](
    step: F,
    var iterator: I,
    *,
    var initial: A,
) raises F.Error -> A where F.First == A and F.Second == _Source[I].Element and F.Out == A

Reduce with a library `Binary` step and no initial value.

def reduce[I, F: Binary](
    step: F,
    var iterator: I,
) raises _ReductionFailure[F.Error] -> F.Out where F.First == F.Out and F.Second == F.Out and _Source[I].Element == F.Out

reduce_optional

Source: fp/iteration/folds.mojo

def reduce_optional[T, I, //, F: def(var T, var T) -> T](
    step: F,
    var iterator: I,
) -> Optional[T] where _Source[I].Element == T

Reduce a source with its first element as the accumulator; empty input gives None.

Only empty input becomes absence. The step runs outside the boundary that detects exhaustion, so a step that raises StopIteration fails as a step.

Parameters

  • T (Movable & Deinitable, inferred): The element and accumulator type.
  • I (Movable & Deinitable, inferred): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.
  • F (def(var T, var T) -> T): The step's type: a plain function or a closure.

Arguments

  • step (F): The step, borrowed; it is called once per element after the first.
  • iterator (var I): The source, consumed.

Returns

Optional[T]: The final accumulator, or None for an empty source.

2 more overloads

Reduce with a raising step; empty input gives `None`, and the step's error is kept.

def reduce_optional[T, I, E: AnyType, //, F: def(var T, var T) raises E -> T](
    step: F,
    var iterator: I,
) raises E -> Optional[T] where _Source[I].Element == T

Reduce with a library `Binary` step; empty input gives `None`.

def reduce_optional[I, F: Binary](
    step: F,
    var iterator: I,
) raises F.Error -> Optional[F.Out] where F.First == F.Out and F.Second == F.Out and _Source[I].Element == F.Out

scan_left

Source: fp/iteration/adapters.mojo

def scan_left[A: Copyable & Deinitable, T, I](
    function: def(var A, var T) thin -> A,
    var initial: A,
    var source: I,
) -> _Scan[A, T, _Source[I]] where _Source[I].Element == T

Lazily yield initial and then the accumulator after each step: n + 1 values for n elements.

The initial value is yielded before the first pull. Each yielded value is a native copy of the accumulator, so retaining them costs their storage; a shared-reference payload is not deep-cloned. For an eager scan with separate carry and output values and no copies, use fp.control.scan.

Parameters

  • A (Copyable & Deinitable): The accumulator type, which must be Copyable.
  • T (Movable & Deinitable): The element type.
  • I (Movable & Deinitable): The source's type: a native iterator, or an owned collection (IterableOwned, such as List), which is consumed.

Arguments

  • function (def(var A, var T) thin -> A): A plain function (var A, var T) -> A, stored.
  • initial (var A): The first accumulator, consumed.
  • source (var I): The source, consumed.

Returns

A ScanIterator, a native iterator of the accumulator snapshots.

2 more overloads

Lazily yield the snapshots of a scan with a closure step.

def scan_left[A: Copyable & Deinitable, T, I, //, F: _LazyStep[A, T]](
    var function: F,
    var initial: A,
    var source: I,
) -> _Scan[A, T, _Source[I], F] where _Source[I].Element == T

Lazily yield the snapshots of a scan with a library `Binary` step.

def scan_left[A: Copyable & Deinitable, I, F: Binary](
    var function: F,
    var initial: A,
    var source: I,
) -> _Scan[A, F.Second, _Source[I], F] where F.First == A and F.Second == _Source[I].Element and F.Out == A and F.Error == Never

Structs

EmptyReductionError

Source: fp/iteration/folds.mojo

struct EmptyReductionError(Copyable, Movable, Writable)

The error of reduce without an initial value on an empty source.

Implements

Copyable, Writable

Iter

Source: fp/iteration/chaining.mojo

struct Iter[I: Iterator](Iterator, IterableOwned)

A native iterator with consuming transformation and terminal methods.

Start a chain with iterated(source). The wrapper stores only the native iterator and preserves its current position and embedded origins. Methods use the same implementations and contracts as the free functions.

Parameters

  • I (Iterator): The concrete native iterator type, including any borrowed origins.

Implements

IterableOwned, Iterator

Aliases

  • Element: The underlying iterator's element type.
  • IteratorOwnedType: Consuming iteration keeps the same wrapper and its position.

Iter.all

def all[T, //, F: def(T) -> Bool](
    deinit self,
    predicate: F,
) -> Bool where I.Element == T

Stop at the first rejected element; empty input returns True.

The predicate borrows each candidate. A decisive result or predicate error stops without another pull. Raising predicates preserve their error type, and library BorrowCallable predicates are supported.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • F (def(T) -> Bool): The native predicate type.

Arguments

  • predicate (F): The predicate, borrowed.

Returns

Bool: True if every element is accepted, otherwise False.

2 more overloads

Test every element with a raising predicate, preserving its error.

def all[T, E, //, F: def(T) raises E -> Bool](
    deinit self,
    predicate: F,
) raises E -> Bool where I.Element == T

Test every element with a library borrowing predicate.

def all[C: BorrowCallable](
    deinit self,
    predicate: C,
) raises C.Failure -> Bool where conforms_to(I.Element, Movable & Deinitable) and C.Payload == I.Element and C.Result == Bool

Iter.any

def any[T, //, F: def(T) -> Bool](
    deinit self,
    predicate: F,
) -> Bool where I.Element == T

Stop at the first accepted element; empty input returns False.

The predicate borrows each candidate. A decisive result or predicate error stops without another pull. Raising predicates preserve their error type, and library BorrowCallable predicates are supported.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • F (def(T) -> Bool): The native predicate type.

Arguments

  • predicate (F): The predicate, borrowed.

Returns

Bool: True if any element is accepted, otherwise False.

2 more overloads

Test any element with a raising predicate, preserving its error.

def any[T, E, //, F: def(T) raises E -> Bool](
    deinit self,
    predicate: F,
) raises E -> Bool where I.Element == T

Test any element with a library borrowing predicate.

def any[C: BorrowCallable](
    deinit self,
    predicate: C,
) raises C.Failure -> Bool where conforms_to(I.Element, Movable & Deinitable) and C.Payload == I.Element and C.Result == Bool

Iter.bounds

def bounds(self) -> Tuple[Int, Optional[Int]]

Return the underlying iterator's remaining length bounds.

Returns

Tuple[Int, Optional[Int]]: The lower bound and optional upper bound, forwarded unchanged.

Iter.collect_list

def collect_list(
    deinit self,
) -> List[Element] where conforms_to(Element, Deinitable)

Alias of to_list; consumes the remaining elements into a list.

Returns

List[Element]: A List[Element], with the same ownership and empty-input behavior as to_list and the free collect_list.

Iter.filter

def filter[T](
    deinit self,
    predicate: def(T) thin -> Bool,
) -> Iter[FilterIterator[T, I]] where I.Element == T

Lazily retain the original elements a borrowing predicate accepts.

The predicate borrows each candidate. Rejected elements are destroyed; accepted elements are moved out unchanged. Plain functions, closures and non-raising BorrowCallable values are supported.

Parameters

  • T (Movable & Deinitable): The source element type.

Arguments

  • predicate (def(T) thin -> Bool): The non-raising predicate, stored.

Returns

Iter[FilterIterator[T, I]]: An Iter over accepted elements, in source order.

2 more overloads

Lazily retain elements with a stored closure predicate.

def filter[T, //, F: def(T) -> Bool](
    deinit self,
    var predicate: F,
) -> Iter[FilterIterator[T, I, F]] where I.Element == T

Lazily retain elements with a library borrowing predicate.

def filter[C: BorrowCallable](
    deinit self,
    var predicate: C,
) -> Iter[FilterIterator[I.Element, I, C]] where conforms_to(I.Element, Movable & Deinitable) and C.Payload == I.Element and C.Result == Bool and C.Failure == Never

Iter.filter_map

def filter_map[T, U](
    deinit self,
    function: def(var T) thin -> Optional[U],
) -> Iter[FilterMapIterator[T, U, I]] where I.Element == T

Lazily transform elements, yielding present values and skipping None.

Moves each element into the callback. Only absent Optional values are skipped; a present Result.Err remains an ordinary element. Library Unary callbacks name the result element parameter explicitly, U=U.

Parameters

  • T (Movable & Deinitable): The source element type.
  • U (Movable & Deinitable): The element inside the returned Optional.

Arguments

  • function (def(var T) thin -> Optional[U]): The non-raising callback returning Optional[U], stored.

Returns

Iter[FilterMapIterator[T, U, I]]: An Iter over present results.

2 more overloads

Lazily transform and filter elements with a stored closure.

def filter_map[T, U, //, F: def(var T) -> Optional[U]](
    deinit self,
    var function: F,
) -> Iter[FilterMapIterator[T, U, I, F]] where I.Element == T

Lazily filter a library `Unary` result; name `U` explicitly.

def filter_map[U, F: Unary](
    deinit self,
    var function: F,
) -> Iter[FilterMapIterator[F.Arg, U, I, F]] where I.Element == F.Arg and F.Out == Optional[U] and F.Error == Never

Iter.find

def find[T, //, F: def(T) -> Bool](
    deinit self,
    predicate: F,
) -> Optional[T] where I.Element == T

Consume through the first accepted element; no match returns None.

The predicate borrows each candidate. The first accepted original value is returned without pulling another element. Raising predicates keep their error type. Library BorrowCallable predicates are also accepted.

Parameters

  • T (Movable & Deinitable, inferred): The element type.
  • F (def(T) -> Bool): The native predicate type.

Arguments

  • predicate (F): The predicate, borrowed.

Returns

Optional[T]: The first accepted element inside Optional, or None.

2 more overloads

Find with a raising predicate, propagating its exact error.

def find[T, E, //, F: def(T) raises E -> Bool](
    deinit self,
    predicate: F,
) raises E -> Optional[T] where I.Element == T

Find with a library borrowing predicate.

def find[C: BorrowCallable](
    deinit self,
    predicate: C,
) raises C.Failure -> Optional[I.Element] where conforms_to(I.Element, Movable & Deinitable) and C.Payload == I.Element and C.Result == Bool

Iter.flat_map

def flat_map[T, U](
    deinit self,
    function: def(var T) thin -> U,
) -> Iter[FlatMapIterator[T, U, I]] where I.Element == T

Lazily expand each element and exhaust its inner source in order.

Moves each element into the callback and retains the returned native iterator or owned iterable until it is exhausted or abandoned. Empty inner sources are skipped. A borrowed inner source retains its external origin. Plain functions, closures and non-raising library Unary values are supported.

Parameters

  • T (Movable & Deinitable): The source element type.
  • U (Movable & Deinitable): The inner iterator or owned iterable returned by the callback.

Arguments

  • function (def(var T) thin -> U): The non-raising callback, stored; move owned captures in with ^.

Returns

Iter[FlatMapIterator[T, U, I]]: An Iter over the concatenated inner elements.

2 more overloads

Lazily expand each element with a stored closure.

def flat_map[T, U, //, F: def(var T) -> U](
    deinit self,
    var function: F,
) -> Iter[FlatMapIterator[T, U, I, F]] where I.Element == T

Lazily expand elements with a library `Unary` value.

def flat_map[F: Unary](
    deinit self,
    var function: F,
) -> Iter[FlatMapIterator[F.Arg, F.Out, I, F]] where I.Element == F.Arg and F.Error == Never

Iter.flatten

def flatten[S](deinit self) -> Iter[_Flatten[I, S]] where I.Element == S

Lazily concatenate inner sources, skipping empty ones.

Exhausts each inner iterator or owned iterable before pulling another outer element. Borrowed inner owners must remain alive and unmoved.

Parameters

  • S (Movable & Deinitable): The inner source type, inferred from this iterator's element type.

Returns

Iter[...]: An Iter over the concatenated inner elements.

Iter.fold_left

def fold_left[A, T, //, F: def(var A, var T) -> A](
    deinit self,
    step: F,
    var initial: A,
) -> A where I.Element == T

Consume elements in order into an accumulator.

Empty input returns initial without calling the step. Steps are never reassociated. The callback is borrowed and may be a plain function, a closure or a library Binary value. Raising overloads propagate the step's exact error type and stop without another pull.

Parameters

  • A (Movable & Deinitable, inferred): The accumulator type.
  • T (Movable & Deinitable, inferred): The source element type.
  • F (def(var A, var T) -> A): The native step type.

Arguments

  • step (F): The step, borrowed for the duration of the fold.
  • initial (var A): The initial accumulator, consumed.

Returns

A: The final accumulator, moved out.

2 more overloads

Fold with a raising step, propagating its exact error type.

def fold_left[A, T, E: AnyType, //, F: def(var A, var T) raises E -> A](
    deinit self,
    step: F,
    var initial: A,
) raises E -> A where I.Element == T

Fold with a library `Binary` step.

def fold_left[A, F: Binary](
    deinit self,
    step: F,
    var initial: A,
) raises F.Error -> A where F.First == A and F.Second == I.Element and F.Out == A

Iter.fold_until

def fold_until[A, B, T, //, F: def(var A, var T) -> ControlFlow[B, A]](
    deinit self,
    step: F,
    var initial: A,
) -> ControlFlow[B, A] where I.Element == T

Fold until Break, or return Continue with the final accumulator.

A break returns immediately without another pull. Empty input returns Continue(initial). Raising overloads preserve the step's error as a separate outcome from a Break. Library Binary steps are also accepted.

Parameters

  • A (Movable & Deinitable, inferred): The accumulator type.
  • B (Movable & Deinitable, inferred): The break payload type.
  • T (Movable & Deinitable, inferred): The source element type.
  • F (def(var A, var T) -> ControlFlow[B, A]): The native step type.

Arguments

  • step (F): The step returning ControlFlow[B, A], borrowed.
  • initial (var A): The initial accumulator, consumed.

Returns

ControlFlow[B, A]: The first Break, or Continue with the final accumulator.

2 more overloads

Fold until `Break` with a raising step, preserving its error.

def fold_until[
    A, B, T, E, //, F: def(var A, var T) raises E -> ControlFlow[B, A],
](
    deinit self,
    step: F,
    var initial: A,
) raises E -> ControlFlow[B, A] where I.Element == T

Fold until `Break` with a library `Binary` step.

def fold_until[B, A, F: Binary](
    deinit self,
    step: F,
    var initial: A,
) raises F.Error -> ControlFlow[B, A] where F.First == A and F.Second == I.Element and F.Out == ControlFlow[B, A]

Iter.map

def map[T, U](
    deinit self,
    function: def(var T) thin -> U,
) -> Iter[MapIterator[T, U, I]] where I.Element == T

Lazily transform each element and continue the chain.

Each element is moved into the stored callback. Construction pulls nothing. Plain functions, capturing closures and non-raising library Unary values use the same admission and execution as the free map.

Parameters

  • T (Movable & Deinitable): The source element type.
  • U (Movable & Deinitable): The result element type.

Arguments

  • function (def(var T) thin -> U): The non-raising callback, stored; move owned captures in with ^.

Returns

Iter[MapIterator[T, U, I]]: An Iter over the transformed elements.

2 more overloads

Lazily transform each element with a stored closure.

def map[T, U, //, F: def(var T) -> U](
    deinit self,
    var function: F,
) -> Iter[MapIterator[T, U, I, F]] where I.Element == T

Lazily transform each element with a library `Unary` value.

def map[F: Unary](
    deinit self,
    var function: F,
) -> Iter[MapIterator[F.Arg, F.Out, I, F]] where I.Element == F.Arg and F.Error == Never

Iter.reduce

def reduce[T, //, F: def(var T, var T) -> T](
    deinit self,
    step: F,
) raises EmptyReductionError -> T where I.Element == T

Reduce from the first element; empty input raises EmptyReductionError.

A non-empty input of length n calls the step n - 1 times. The overload with initial= instead folds every element from that accumulator. Raising uninitialized reductions distinguish empty input and step failure with ReductionError[E]; initialized reductions propagate E directly. Library Binary steps preserve the same contracts.

Parameters

  • T (Movable & Deinitable, inferred): The element and accumulator type.
  • F (def(var T, var T) -> T): The native step type.

Arguments

  • step (F): The step, borrowed.

Returns

T: The reduced value, moved out.

Raises

EmptyReductionError: EmptyReductionError: The source is empty and no initializer was supplied.

5 more overloads

Reduce with a raising step, distinguishing step failure from empty input.

def reduce[T, E, //, F: def(var T, var T) raises E -> T](
    deinit self,
    step: F,
) raises ReductionError[E] -> T where I.Element == T

Reduce from the first element with a library `Binary` step.

def reduce[F: Binary](
    deinit self,
    step: F,
) raises _ReductionFailure[F.Error] -> F.Out where F.First == F.Out and F.Second == F.Out and I.Element == F.Out

Reduce from an explicit initial accumulator, as `fold_left` does.

def reduce[A, T, //, F: def(var A, var T) -> A](
    deinit self,
    step: F,
    *,
    var initial: A,
) -> A where I.Element == T

Reduce from an initial accumulator, preserving the step's error.

def reduce[A, T, E, //, F: def(var A, var T) raises E -> A](
    deinit self,
    step: F,
    *,
    var initial: A,
) raises E -> A where I.Element == T

Reduce from an initial accumulator with a library `Binary` step.

def reduce[A, F: Binary](
    deinit self,
    step: F,
    *,
    var initial: A,
) raises F.Error -> A where F.First == A and F.Second == I.Element and F.Out == A

Iter.reduce_optional

def reduce_optional[T, //, F: def(var T, var T) -> T](
    deinit self,
    step: F,
) -> Optional[T] where I.Element == T

Reduce from the first element, returning None for empty input.

Only empty input becomes absence. Raising overloads propagate the exact step error, including StopIteration, and stop without another pull. Library Binary steps are also accepted.

Parameters

  • T (Movable & Deinitable, inferred): The element and accumulator type.
  • F (def(var T, var T) -> T): The native step type.

Arguments

  • step (F): The step, borrowed.

Returns

Optional[T]: The reduced value inside Optional, or None.

2 more overloads

Reduce with a raising step; only empty input becomes `None`.

def reduce_optional[T, E: AnyType, //, F: def(var T, var T) raises E -> T](
    deinit self,
    step: F,
) raises E -> Optional[T] where I.Element == T

Reduce with a library `Binary` step, returning `None` for empty input.

def reduce_optional[F: Binary](
    deinit self,
    step: F,
) raises F.Error -> Optional[F.Out] where F.First == F.Out and F.Second == F.Out and I.Element == F.Out

Iter.scan_left

def scan_left[A: Copyable & Deinitable, T](
    deinit self,
    step: def(var A, var T) thin -> A,
    var initial: A,
) -> Iter[ScanIterator[A, T, I]] where I.Element == T

Lazily yield the initial accumulator and a copy after each step.

The first output copies initial without pulling an input. Each later output applies the step once, then copies the accumulator. An input of length n yields n + 1 snapshots. Closures and non-raising library Binary steps retain the same contract as the free scan_left.

Parameters

  • A (Copyable & Deinitable): The copyable accumulator type.
  • T (Movable & Deinitable): The source element type.

Arguments

  • step (def(var A, var T) thin -> A): The non-raising step, stored.
  • initial (var A): The initial accumulator, consumed.

Returns

Iter[ScanIterator[A, T, I]]: An Iter over the accumulator snapshots.

2 more overloads

Lazily yield accumulator snapshots with a stored closure.

def scan_left[A: Copyable & Deinitable, T, //, F: def(var A, var T) -> A](
    deinit self,
    var step: F,
    var initial: A,
) -> Iter[ScanIterator[A, T, I, F]] where I.Element == T

Lazily yield accumulator snapshots with a library `Binary` step.

def scan_left[A: Copyable & Deinitable, F: Binary](
    deinit self,
    var step: F,
    var initial: A,
) -> Iter[ScanIterator[A, F.Second, I, F]] where F.First == A and F.Second == I.Element and F.Out == A and F.Error == Never

Iter.to_list

def to_list(deinit self) -> List[Element] where conforms_to(Element, Deinitable)

Consume the remaining elements into a list, in order.

Elements must be deinitializable, as for the free collect_list. Each element moves into the result; no copy requirement is added. Takes linear time and storage in the number of remaining elements.

Returns

List[Element]: A List[Element]; an empty list when the source is exhausted.

ReductionStepError

Source: fp/iteration/folds.mojo

struct ReductionStepError[E](Movable, Copyable where conforms_to(E, Copyable))

A reduction step's error, kept distinct from empty input.

A step that itself raises EmptyReductionError is still reported in this alternative.

Parameters

  • E (Movable & Deinitable): The step's error type.

Implements

Copyable

Fields

  • error (E): The step's error, unchanged.

ReductionStepError.into_error

def into_error(deinit self) -> E

Consume the wrapper and return the step's error.

Returns

E: The step's error, moved out.

Aliases

FilterIterator

Source: fp/iteration/adapters.mojo

comptime FilterIterator[T, I: Iterator, F: Movable & Deinitable = def(T) thin -> Bool] = _Filter[T, I, F]

The type filter returns, for a generic function's return annotation.

Parameters

  • T (Movable & Deinitable): The element type.
  • I (Iterator): The native iterator over the source.
  • F (Movable & Deinitable): The predicate's type; the thin function type by default.

FilterMapIterator

Source: fp/iteration/adapters.mojo

comptime FilterMapIterator[T, U, I: Iterator, F: Movable & Deinitable = def(var T) thin -> Optional[U]] = _FilterMap[T, U, I, F]

The type filter_map returns, for a generic function's return annotation.

Parameters

  • T (Movable & Deinitable): The element type.
  • U (Movable & Deinitable): The type of a present result.
  • I (Iterator): The native iterator over the source.
  • F (Movable & Deinitable): The function's type; the thin function type by default.

FlatMapIterator

Source: fp/iteration/adapters.mojo

comptime FlatMapIterator[T, U, I: Iterator, F: Movable & Deinitable = def(var T) thin -> U] = _Flatten[_Map[T, U, I, F], U]

The type flat_map returns, for a generic function's return annotation.

Parameters

  • T (Movable & Deinitable): The element type.
  • U (Movable & Deinitable): The inner source the function returns, not the final element.
  • I (Iterator): The native iterator over the source.
  • F (Movable & Deinitable): The function's type; the thin function type by default.

MapIterator

Source: fp/iteration/adapters.mojo

comptime MapIterator[T, U, I: Iterator, F: Movable & Deinitable = def(var T) thin -> U] = _Map[T, U, I, F]

The type map returns, for a generic function's return annotation.

Parameters

  • T (Movable & Deinitable): The element type.
  • U (Movable & Deinitable): The result type.
  • I (Iterator): The native iterator over the source.
  • F (Movable & Deinitable): The function's type; the thin function type by default.

ReductionError

Source: fp/iteration/folds.mojo

comptime ReductionError[E] = Variant[ EmptyReductionError, ReductionStepError[E] ]

The error of a raising reduce without an initial value: empty input, or the step's error.

A native Variant; check which alternative is active before taking it.

Parameters

  • E (Movable & Deinitable): The step's error type.

ScanIterator

Source: fp/iteration/adapters.mojo

comptime ScanIterator[A: Copyable & Deinitable, T, I: Iterator, F: Movable & Deinitable = def(var A, var T) thin -> A] = _Scan[A, T, I, F]

The type scan_left returns, for a generic function's return annotation.

Parameters

  • A (Copyable & Deinitable): The accumulator type.
  • T (Movable & Deinitable): The element type.
  • I (Iterator): The native iterator over the source.
  • F (Movable & Deinitable): The step's type; the thin function type by default.

Fold scalars, SIMD vectors and documents with one function

generic_fold.mojo Download
"""The same sequential fold over scalar, SIMD and a user-defined document."""
from fp.iteration import fold_left
from std.iter import iter
from std.testing import assert_equal

def scalar(var total: Int, var value: Int) -> Int: return total + value
def vector[dtype: DType, width: Int](var total: SIMD[dtype, width],
                                   var value: SIMD[dtype, width]) -> SIMD[dtype, width]:
    return total + value

@fieldwise_init
struct Document(Movable):
    var text: String
    var words: Int

def append_word(var document: Document, var word: String) -> Document:
    if document.words: document.text += " "
    document.text += word
    document.words += 1
    return document^

def vectors[dtype: DType, width: Int]() raises:
    comptime V = SIMD[dtype, width]
    var first = V(0)
    var second = V(0)
    comptime for lane in range(width):
        first[lane] = Scalar[dtype](lane + 1)
        second[lane] = Scalar[dtype](10 + lane)
    var inputs: List[V] = [first, second]
    var expected = V(0)
    for value in inputs: expected += value
    var actual = fold_left(vector[dtype, width], V(0), iter(inputs))
    comptime assert type_of(actual) == V
    assert_equal(actual, expected)
    assert_equal(actual.reduce_add(), Scalar[dtype](11 * width + width * (width - 1)))
    assert_equal(fold_left(vector[dtype, width], first, List[V]()), first)

def main() raises:
    var numbers: List[Int] = [1, 2, 3]
    var expected = 0
    for value in numbers: expected += value
    assert_equal(fold_left(scalar, 0, iter(numbers)), expected)
    assert_equal(fold_left(scalar, 7, List[Int]()), 7)
    vectors[DType.int32, 4]()
    vectors[DType.float64, 2]()
    var words: List[String] = ["native", "functional", "composition"]
    var native = Document(String(), 0)
    for word in words: native = append_word(native^, word)
    var document = fold_left(append_word, Document(String(), 0), words^)
    assert_equal(document.text, native.text)
    assert_equal(document.words, native.words)
    var empty = fold_left(append_word, document^, List[String]())
    assert_equal(empty.text, "native functional composition")
    assert_equal(empty.words, 3)
    print("scalar=", expected, "; document=", empty.text)

Run from the repository root pixi run mojo run -I src docs/examples/generic_fold.mojo

Output

scalar= 6 ; document= native functional composition

fold_left returns the accumulator type its step returns. Over [1, 2, 3] with scalar it returns 6, and over an empty list it returns the initial 7. Over SIMD vectors, vector adds lane by lane and the result is still a vector, equal to the hand-written loop; no lanes are reduced. Over three words, append_word builds the Document "native functional composition" with a word count of 3, the same as the loop in main.