Passing and returning generators
Use Generator[T] to accept or return a generator:
def once(n: i64) -> Generator[i64]:
yield n
def pair() -> Generator[i64]:
yield 10
yield 20
def source(n: i64) -> Generator[i64]:
once(n)
def total(values: Generator[i64]) -> Result[i64, OverflowError[i64]]:
mut result = 0
for value in values:
result = result + value
Ok(result)
def main() -> Result[(), IoError | OverflowError[i64]]:
print(total(source(7))?)?
print(total(pair())?)?
Ok(())
7
30
total accepts either producer. Passing a generator transfers ownership; use
&mut Generator[T] when a helper should advance an existing owner with next.
Once you know closures, Transform a stream of values
shows how to filter, map and reduce a generator without writing the loop.
A factory must return the same producer on every path. Two generators yielding the same type are not interchangeable return values:
def one() -> Generator[i64]:
yield 1
def two() -> Generator[i64]:
yield 2
yield 3
def choose(flag: bool) -> Generator[i64]:
if flag:
return one()
two()
def main() -> ():
drop(choose(True))
expected Generator[i64] from `one`, got Generator[i64] from `two`
Put such a branch inside one generator body instead. A generator may contain another generator, but recursive generator state is rejected: its inline storage would have no finite size.