Creating Our Own Streams
Learn how to create different types of streams in Elixir
We'll cover the following
Streams are implemented solely in Elixir libraries. There’s no specific runtime support. However, this doesn’t mean we want to drop down to the very lowest level and create our own streamable types. The actual implementation is complex. Instead, we probably want to use some helpful wrapper functions to do the heavy lifting. There are a number of these, including cycle
, repeatedly
, iterate
, unfold
, and resource
.
Let’s start with the three simplest: cycle
, repeatedly
, and iterate
.
Stream.cycle
Stream.cycle
takes an enumerable and returns an infinite stream containing that enumerable’s elements. When it gets to the end, it repeats from the beginning, indefinitely. Here’s an example that generates the rows in an HTML table with alternating green
and white
classes:
iex> Stream.cycle(~w{ green white }) |>
...> Stream.zip(1..5) |>
...> Enum.map(fn {class, value} ->
...> "<tr class='#{class}'><td>#{value}</td></tr>\n" end) |>
...> IO.puts
<tr class="green"><td>1</td></tr>
<tr class="white"><td>2</td></tr>
<tr class="green"><td>3</td></tr>
<tr class="white"><td>4</td></tr>
<tr class="green"><td>5</td></tr>
:ok
Stream.repeatedly
Stream.repeatedly
takes a function and invokes it each time a new value is wanted.
iex> Stream.repeatedly(fn -> true end) |> Enum.take(3)
[true, true, true]
iex> Stream.repeatedly(&:random.uniform/0) |> Enum.take(3)
[0.7230402056221108, 0.94581636451987, 0.5014907142064751]
Stream.iterate
Stream.iterate(start_value, next_fun)
generates an infinite stream. The first value is start_value
. The next value is generated by applying next_fun
to this value. This continues for as long as the stream is being used, with each value being the result of applying next_fun
to the previous value.
Here are some examples:
iex> Stream.iterate(0, &(&1+1)) |> Enum.take(5)
[0, 1, 2, 3, 4]
iex> Stream.iterate(2, &(&1*&1)) |> Enum.take(5)
[2, 4, 16, 256, 65536]
iex> Stream.iterate([], &[&1]) |> Enum.take(5)
[[], [[]], [[[]]], [[[[]]]], [[[[[]]]]]]
Practice these commands in the given terminal:
Get hands-on with 1400+ tech skills courses.