Stream - laziness

Stream module supports lazy operations:

      iex> 1..100 |> Stream.map(&(&1 * 3)) |> Stream.filter(&(rem(&1 , 2) == 0)) |> Enum.sum
       7650

instead of generating intermediate lists, Stream builds a series of computations that are invoked only when we pass the underlying stream to the Enum module

       x  |> Stream.filter(fn a -> a[:color] == RED end)
          |> Stream.map(fn a -> a[:weight] end)
          |> Stream.take(5)
          |> Enum.to_list

for example, Range is a stream:

   iex> 1..3 |> Stream.map(rg, &(&1 * 2)) |> Enum.map(&(&1 + 1))
   [3, 5, 7]

Stream.unfold/2

can be used to generate values from a given initial value:

  iex> Stream.unfold("hello", &String.next_codepoint/1) |> Enum.take(3)
    ["h", "e", "l"]

Stream.resource/3

wraps around resources, guaranteeing they are opened right before enumeration and closed afterwards, even in the case of failures:

  iex> File.stream!("path/to/file") |> Enum.take(10)
читает первые десять строк файла в [String]

drop/2      drop_while/2 
take/2      take_while/2 

filter/2    reject/2

map/2       each/2       scan/2
unfold/2    zip/2 

Stream.each/2 - для сайд-эффектов на стримах (аналогична mapM в Хаскеле)

iex> Stream.each([1, 2, 3], fn(x) -> send self(), x end) |> Enum.to_list        
[1, 2, 3]
iex> receive do: (x -> x)
 1
iex> receive do: (x -> x)
 2
iex> receive do: (x -> x)
 3