Hi!
I’d like to present streaming - a macro for creating streams much like the special form for
.
streaming x <- 1..10, y <- 11..20, z <- 21..30 do
{x, y, z}
end
creates a stream of all combinations of x, y, and z.
The main difference between streaming
and for
is that streaming
is lazy and always returns a stream.
The reduce
option is by design not supported since this cannot be done lazily. Just use for
or Enum.reduce
for this.
However, streaming
instead provides convenient syntax for transforming a stream using the transform
option.
streaming i <- 1..100, transform: StringIO.open("string") |> elem(1) do
pid ->
case IO.getn(pid, "", 1) do
:eof -> {:halt, pid}
char -> {[{i, char}], pid}
end
after
pid -> StringIO.close(pid)
end
|> Enum.to_list()
=> [{1, "s"}, {2, "t"}, {3, "r"}, {4, "i"}, {5, "n"}, {6, "g"}]
streaming
also provides unfold
, scan
, resource
options that works like corresponding functions in the Stream module.
Bitstring generators are also supported and can be combined with the other options.
The into
option is based on Stream.into/3
and thus collects values into a collectable as a side-effect instead of returning the collectable.
Please see the GitHub repo for more examples:
Half-way through making this library I discovered lazy_for, but streaming
is arguably more feature complete.