Iter

Iter Builtin.Iter(item) :: # (opaque)
custom : state, [Known(U64), Unknown], (state -> Try((item, state), [NoMore])) -> Iter(item)
range_exclusive : num, num -> Iter(num) where [num.range_exclusive : num, num -> Iter(num)]

Iterator over num values from start up to but not including end. Returns an empty iterator if start >= end. Generic sugar for the range_exclusive method that start..<end dispatches on the bound type.

range_inclusive : num, num -> Iter(num) where [num.range_inclusive : num, num -> Iter(num)]

Iterator over num values from start up to and including end. Returns an empty iterator if start > end. Generic sugar for the range_inclusive method that start..=end dispatches on the bound type.

exclusive_range : num, num, [Known(U64), Unknown] -> Iter(num)
    where [
        num.is_lt : num, num -> Bool,
        num.plus_try : num, num -> Try(num, [Overflow]),
        num.from_numeral : Numeral -> Try(num, [InvalidNumeral(Str)]),
    ]
inclusive_range : num, num, [Known(U64), Unknown] -> Iter(num)
    where [
        num.is_lte : num, num -> Bool,
        num.plus_try : num, num -> Try(num, [Overflow]),
        num.from_numeral : Numeral -> Try(num, [InvalidNumeral(Str)]),
    ]
iter : Iter(item) -> Iter(item)
single : item -> Iter(item)

Returns an iterator that yields exactly one item.

expect Iter.fold(Iter.single(42.I64), [], |acc, item| acc.append(item)) == [42]
prepended : Iter(item), item -> Iter(item)

Returns an iterator that yields the given item first, followed by everything the given iterator yields.

The compiler uses this to assemble the iterator it passes to from_interpolation when checking an interpolated string literal.

expect Iter.fold([2, 3].iter().prepended(1), [], |acc, item| acc.append(item)) == [1, 2, 3]
concat : Iter(item), Iter(item) -> Iter(item)

Returns an iterator that yields all items from the first iterator, then all items from the second iterator.

expect Iter.fold([1.I64, 2].iter().concat([3, 4].iter()), [], |acc, item| acc.append(item)) == [1, 2, 3, 4]
append : Iter(item), item -> Iter(item)

Returns an iterator that yields everything from the given iterator, followed by the given item.

expect Iter.fold([1.I64, 2].iter().append(3), [], |acc, item| acc.append(item)) == [1, 2, 3]
next : Iter(item) -> [One({ item : item, rest : Iter(item) }), Skip({ rest : Iter(item) }), Done]
map : Iter(a), (a -> b) -> Iter(b)
keep_if : Iter(a), (a -> Bool) -> Iter(a)
drop_if : Iter(a), (a -> Bool) -> Iter(a)
fold : Iter(a), acc, (acc, a -> acc) -> acc
sum : Iter(item) -> item where [item.plus : item, item -> item, item.default : () -> item]

Sum the items of an iterator, without collecting them into a list first. Works for any type that implements plus and default methods, such as the numeric types.

default is called only when the iterator is empty; otherwise it is never called at all. Summing begins at the first item and uses plus to combine the rest, so a single-item iterator returns that item without calling either method, and default does not need to be an identity value for plus.

expect (1..=4).sum() == 10

expect [42.I64].iter().sum() == 42

expect [].iter().sum() == 0.I64
product : Iter(item) -> Try(item, [IterWasEmpty]) where [item.times : item, item -> item]

Multiply the items of an iterator together, or Err(IterWasEmpty) if the iterator is empty. Works for any type that implements times.

Unlike Iter.sum, this reports an empty iterator instead of answering it. default is zero for the numeric types, which is the identity for plus but not for times, so there is no value it could return for an empty iterator that would keep product consistent with multiplication.

expect (1..=4).product() == Ok(24)

expect [42.I64].iter().product() == Ok(42)

expect [7.I64].iter().drop_first(1).product() == Err(IterWasEmpty)
min : Iter(item) -> Try(item, [IterWasEmpty]) where [item.min : item, item -> item]

Find the minimum item of an iterator, or Err(IterWasEmpty) if the iterator is empty. Works for any type that implements min.

expect [3.I64, 1, 2].iter().min() == Ok(1)

expect [7.I64].iter().drop_first(1).min() == Err(IterWasEmpty)
max : Iter(item) -> Try(item, [IterWasEmpty]) where [item.max : item, item -> item]

Find the maximum item of an iterator, or Err(IterWasEmpty) if the iterator is empty. Works for any type that implements max.

expect [3.I64, 1, 2].iter().max() == Ok(3)

expect [7.I64].iter().drop_first(1).max() == Err(IterWasEmpty)
size_hint : Iter(item) -> [Known(U64), Unknown]

Returns the iterator's length if it is known up front, so collections can pre-size their allocation.

collect : Iter(item) -> output where [output.from_iter : Iter(item) -> output]

Collect this iterator into any output type that provides from_iter.

stream : Iter(item) -> Stream(item)

Lift this pure iterator into an effectful Stream, so it can be combined with effectful operations like Stream.map.

take_first : Iter(item), U64 -> Iter(item)

Returns an iterator that yields at most the first n items of this iterator. If the source has fewer than n items, all of them are yielded.

expect Iter.fold(Iter.take_first(List.iter([1, 2, 3, 4, 5]), 3), [], |acc, item| acc.append(item)) == [1, 2, 3]

expect Iter.fold(Iter.take_first(List.iter([1, 2]), 5), [], |acc, item| acc.append(item)) == [1, 2]
drop_first : Iter(item), U64 -> Iter(item)

Returns an iterator that skips the first n items of this iterator. If the source has n or fewer items, the result is empty.

expect Iter.fold(Iter.drop_first(List.iter([1, 2, 3, 4, 5]), 2), [], |acc, item| acc.append(item)) == [3, 4, 5]

expect Iter.fold(Iter.drop_first(List.iter([1, 2, 3]), 10), [], |acc, item| acc.append(item)) == []
take_last : Iter(item), U64 -> Iter(item)

Returns an iterator that yields the last n items of this iterator. If the source has fewer than n items, all of them are yielded.

When the source iterator's length is unknown, this materializes the source into a list to find where the last n items begin. Avoid calling this on iterators whose length is unknown and might be huge.

expect Iter.fold(Iter.take_last(List.iter([1, 2, 3, 4, 5]), 3), [], |acc, item| acc.append(item)) == [3, 4, 5]

expect Iter.fold(Iter.take_last(List.iter([1, 2]), 5), [], |acc, item| acc.append(item)) == [1, 2]
drop_last : Iter(item), U64 -> Iter(item)

Returns an iterator that yields all items except the last n. If the source has n or fewer items, the result is empty.

When the source iterator's length is unknown, this materializes the source into a list to find where the last n items begin. Avoid calling this on iterators whose length is unknown and might be huge.

expect Iter.fold(Iter.drop_last(List.iter([1, 2, 3, 4, 5]), 2), [], |acc, item| acc.append(item)) == [1, 2, 3]

expect Iter.fold(Iter.drop_last(List.iter([1, 2, 3]), 10), [], |acc, item| acc.append(item)) == []
step_by : Iter(item), U64 -> Iter(item)

Returns an iterator that yields the first item and then every nth item after it, skipping the n - 1 items in between. A step of 0 yields an empty iterator.

expect Iter.fold(Iter.step_by(List.iter([1, 2, 3, 4, 5]), 2), [], |acc, item| acc.append(item)) == [1, 3, 5]

expect Iter.fold(Iter.step_by(List.iter([1, 2, 3]), 0), [], |acc, item| acc.append(item)) == []
rev : Iter(item) -> Iter(item)

Returns an iterator that yields this iterator's items in reverse order.

Because an Iter only moves forward, this materializes the source into a list to reverse it. The result always has a known length, so collecting it is efficient. Avoid calling this on iterators whose length is unknown and might be huge.

expect Iter.fold(Iter.rev(List.iter([1, 2, 3])), [], |acc, item| acc.append(item)) == [3, 2, 1]

expect Iter.fold(Iter.rev(List.iter([])), [], |acc, item| acc.append(item)) == []