baml.iter.Peekable

The iterator `baml.iter.Iterator.peekable` returns.

Reference version

Signature

class baml.iter.Peekable<T, E>

The iterator baml.iter.Iterator.peekable returns.

Wraps a source with room for one look-ahead element, so a caller can decide what to do with an element before committing to consuming it. The buffer holds at most one item, filled by peek and drained by the following next.

has_buffer is a separate flag rather than a Done in buffer because Done is also a legitimate buffered answer: a peek at the end of the source has to be remembered as "peeked, and the answer was Done".

Source:<builtin>/baml/ns_iter/iter.bamlbytes 3451736099

Fields

buffer

T | baml.iter.Done

The look-ahead slot: the element a peek pulled, or Done if the peek hit the end. Meaningful only while has_buffer is true.

has_buffer

bool

Whether buffer currently holds a peeked answer.

Instance methods

function

peek

(self) -> T | baml.iter.Done throws E

Returns the element the next next will return, or baml.iter.Done if there is none, without consuming it.

The item is buffered, so the following next returns the same one and repeated peek calls do not advance the source.

Throws

  • E if advancing the source fails. Nothing is buffered in that case, so a retry pulls again rather than replaying the failure.

Implementations

baml.Concrete for T

Source:<builtin>/baml/core.bamlbytes 747779

baml.iter.Iterable for baml.iter.Peekable<T, E>

Item = TError = E

Instance methods

Source:<builtin>/baml/ns_iter/iter.bamlbytes 3555235730

baml.iter.Iterator for baml.iter.Peekable<T, E>

Item = TError = E

Instance methods

function

chain

<E2>(
self,
other: baml.iter.Iterable<Error = E2, Item = (Self as baml.iter.Iterator).Item>
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over all of self's elements followed by all of other's.

other.iter() is called right away, when the chain is built; only the advancing is deferred. The two sides may have different error types, and the result throws either.

Returns

A baml.iter.Chain.

function

collect

(self) -> (Self as baml.iter.Iterator).Item[] throws (Self as baml.iter.Iterator).Error

Consumes the rest of this iterator into an array, in order.

The rest: elements already pulled from a partly-consumed iterator are not included, and an already-exhausted iterator collects to [].

Throws

  • Self.Error if advancing the iterator fails. The elements gathered so far are lost, since the array is only returned on success.
function

count

(self) -> int throws (Self as baml.iter.Iterator).Error

Consumes the rest of this iterator and returns how many elements there were, 0 if it was already exhausted.

Every element is actually pulled — there is no size hint to short circuit with — so counting a chain runs the whole chain, callbacks included.

Throws

  • Self.Error if advancing the iterator fails.
function

every

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> bool throws (Self as baml.iter.Iterator).Error | E2

Whether predicate holds for every remaining element — Python's all, JavaScript's every.

Short circuits at the first false. An empty iterator gives true — the empty conjunction — which is worth remembering when the iterator may have been exhausted already.

Throws

  • Self.Error if advancing the iterator fails.
  • E2 if predicate throws.

ALIASES: all

function

filter

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over the elements for which predicate is true, in order.

A rejected element is skipped, not a stopping point — use baml.iter.Iterator.take_while to stop at the first failure instead.

Returns

A baml.iter.Filter yielding the kept elements.

function

filter_map

<R, E2>(
self,
fn: ((Self as baml.iter.Iterator).Item) -> R | null throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = R>

Returns an iterator over the non-null results of fn: map and filter in one pass.

null is the skip signal, so the produced item type R is the non-optional one. An iterator whose own items you want to keep as null cannot be expressed this way — filter and map it in two steps instead.

Returns

A baml.iter.FilterMap yielding the non-null results, in order.

function

find

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> (Self as baml.iter.Iterator).Item | null throws (Self as baml.iter.Iterator).Error | E2

The first remaining element for which predicate is true, or null if the iterator runs out first.

Short circuits: the matching element is consumed, and the iterator is left positioned just after it.

The result is Self.Item?, so — unlike next, which uses the distinct baml.iter.Done sentinel — an iterator whose items are themselves nullable cannot tell a found null from no match. Use baml.iter.Iterator.filter followed by next when that distinction matters.

Throws

  • Self.Error if advancing the iterator fails.
  • E2 if predicate throws.
function

flat_map

<R, E2, E3>(
self,
fn: ((Self as baml.iter.Iterator).Item) -> baml.iter.Iterable<Error = E3, Item = R> throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2 | E3, Item = R>

Returns an iterator over the elements of the iterables fn produces, laid end to end.

Each inner sequence is drained before the next outer element is pulled, and one that is empty contributes nothing. Three error types meet here — the source's, fn's E2, and the inner iterables' E3 — and the result throws all of them.

Returns

A baml.iter.FlatMap yielding R.

function

for_each

<E2>(
self,
fn: ((Self as baml.iter.Iterator).Item) -> void throws E2
) -> void throws (Self as baml.iter.Iterator).Error | E2

Calls fn on each remaining element, in order, for its side effects.

A for (.. in ..) loop is generally preferable; this is for the end of a long chain of calls. It runs to exhaustion — there is no way for fn to stop it early. Use baml.iter.Iterator.some or a for loop with a break when you need to.

Throws

  • Self.Error if advancing the iterator fails.
  • E2 if fn throws, which ends the traversal at that element.
function

map

<R, E2>(
self,
fn: ((Self as baml.iter.Iterator).Item) -> R throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = R>

Returns an iterator that applies fn to each element — Python's map, JavaScript's Iterator.prototype.map.

fn is applied exactly once per element that is actually pulled, in order, so a chain that ends early never touches the elements it skipped.

Returns

A baml.iter.Map yielding R, of the same length as self.

function

peekable

(
self
) -> baml.iter.Peekable<(Self as baml.iter.Iterator).Item, (Self as baml.iter.Iterator).Error>

Returns an iterator with one element of look-ahead.

Unlike the other adapters this returns the concrete baml.iter.Peekable class rather than the Iterator interface, because peek lives on the class: an existential would hide it.

Returns

A baml.iter.Peekable yielding exactly what self yields, plus a peek that reads the next element without consuming it.

function

reduce

<A, E2>(
self,
fn: (A, (Self as baml.iter.Iterator).Item) -> A throws E2,
initial: A
) -> A throws (Self as baml.iter.Iterator).Error | E2

Folds every remaining element into an accumulator, left to right.

The accumulator starts at initial and each call to fn replaces it with the result; initial is what comes back for an empty iterator. Because the seed is required and its type A is independent of the item type, this is the operation Rust calls Iterator::fold and Python calls functools.reduce — not Rust's reduce.

Parameters

  • fn: combines the accumulator so far with the next element.
  • initial: the starting accumulator, and the result for an empty iterator.

Throws

  • Self.Error if advancing the iterator fails.
  • E2 if fn throws. The fold stops there; the partial accumulator is not recoverable.

ALIASES: fold

function

skip

(
self,
n: int
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over everything after the first n elements.

For n <= 0 every element is yielded; a source with fewer than n elements yields nothing. The skipped elements are pulled from the source and discarded — they are not free, and they can still throw. A skip is counted only once the source has actually yielded, so a throw the caller retries does not consume part of the count.

Parameters

  • n: how many leading elements to discard.

Returns

A baml.iter.Skip.

Examples

baml.iter.Range.new(0, 5).skip(2).collect() // [2, 3, 4]
function

skip_while

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over everything from the first element predicate rejects onwards.

That first rejected element is itself yielded — it is the start of the kept run, not a discarded boundary. The predicate is not consulted again afterwards, so later elements it would have matched are still yielded.

Returns

A baml.iter.SkipWhile.

Examples

// stops skipping at 3, so the trailing 1 and 2 are kept
[1, 2, 3, 1, 2].iter().skip_while((x: int) -> bool { x < 3 }).collect() // [3, 1, 2]
function

some

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> bool throws (Self as baml.iter.Iterator).Error | E2

Whether predicate holds for any remaining element — Python's any, JavaScript's some.

Short circuits at the first true, leaving the iterator positioned just after the matching element so it can be inspected further. An empty iterator gives false, the empty disjunction.

Throws

  • Self.Error if advancing the iterator fails.
  • E2 if predicate throws.

ALIASES: any

function

step_by

(
self,
n: int
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over every nth element, starting with the first.

The elements kept are those at positions 0, n, 2n, and so on. The skipped ones are still pulled from the source — and so may still throw — they are simply discarded.

Parameters

  • n: how far to advance between yielded elements. Values below 1 mean "advance by one", i.e. yield everything.

Returns

A baml.iter.StepBy.

function

take

(
self,
n: int
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over at most the first n elements.

Once n elements have been yielded the source is no longer advanced, and if the source ends first this ends with it. For n <= 0 it yields nothing. A slot is spent only once the source has actually yielded an element, so a source that throws and is then retried does not silently lose one.

This is the usual way to bound an unbounded iterator such as Repeat.new(v) or a wide Range.

Parameters

  • n: the greatest number of elements to yield.

Returns

A baml.iter.Take yielding at most n elements.

Examples

baml.iter.Repeat.new(0).take(5).collect()   // [0, 0, 0, 0, 0]
baml.iter.Range.new(0, 10).take(3).collect() // [0, 1, 2]
function

take_while

<E2>(
self,
predicate: ((Self as baml.iter.Iterator).Item) -> bool throws E2
) -> baml.iter.Iterator<Error = (Self as baml.iter.Iterator).Error | E2, Item = (Self as baml.iter.Iterator).Item>

Returns an iterator over the leading run of elements for which predicate is true.

The element that fails the predicate is consumed from the source and is not yielded. Unlike filter, iteration stops at the first failure rather than skipping it, and the stop latches: the source is never advanced again, however often next is called.

Returns

A baml.iter.TakeWhile.

Examples

// stops at 5, so 6 and 8 are never yielded
[2, 4, 5, 6, 8].iter().take_while((x: int) -> bool { x % 2 == 0 }).collect() // [2, 4]

Source:<builtin>/baml/ns_iter/iter.bamlbytes 3573636097