Caffeine v1.2.0 Caffeine.Stream

Primitives and HOFs

Examples

iex> defmodule Fibonacci do
...>   import Caffeine.Stream, only: [construct: 2]
...> 
...>   def stream do
...>     stream(0, 1)
...>   end
...> 
...>   defp stream(a, b) do
...>     rest = fn -> stream(b, a + b) end
...>     construct(a, rest)
...>   end
...> end
iex> require Integer
iex> Fibonacci.stream()
...> |> Caffeine.Stream.filter(&Integer.is_even/1)
...> |> Caffeine.Stream.map(&Integer.to_string/1)
...> |> Caffeine.Stream.take(10)
["0", "2", "8", "34", "144", "610", "2584", "10946", "46368", "196418"]

Link to this section Summary

Types

t()

The Caffeine.Stream data structure

Functions

A stream of at least one element h

Predicate: is s a stream of at least one element?

A stream whose elements prescribe to the predicate p

The head, if any, of the stream s

Like the stream s with the function f applied to each element

This signals the end of a stream

Predicate: is s the sentinel?

The tail, if any, of the stream s

A list of n consecutive elements from the stream s

Link to this section Types

Link to this opaque t() (opaque)
t()

The Caffeine.Stream data structure

Link to this section Functions

Link to this function construct(h, t)
construct(Caffeine.Element.t(), (() -> t())) :: t()

A stream of at least one element h

Link to this function construct?(s)
construct?(t()) :: boolean()

Predicate: is s a stream of at least one element?

Examples

iex> import Caffeine.Stream, only: [construct?: 1, sentinel: 0, construct: 2]
Caffeine.Stream
iex> construct?(construct("Elixir", fn -> sentinel() end))
true
iex> construct?(sentinel())
false
Link to this function filter(s, p)
filter(t(), (Caffeine.Element.t() -> boolean())) :: t()

A stream whose elements prescribe to the predicate p

Examples

iex> defmodule Natural do
...>   import Caffeine.Stream, only: [construct: 2]
...> 
...>   def stream do
...>     stream(0)
...>   end
...> 
...>   defp stream(n) do
...>     rest = fn -> stream(increment(n)) end
...>     construct(n, rest)
...>   end
...> 
...>   defp increment(n) do
...>     n + 1
...>   end
...> end
iex> require Integer
iex> Natural.stream()
...> |> Caffeine.Stream.filter(&Integer.is_even/1)
...> |> Caffeine.Stream.take(5)
[0,2,4,6,8]

The head, if any, of the stream s

The following always holds true head(construct(X, Y)) == X.

Examples

iex> import Caffeine.Stream, only: [head: 1, sentinel: 0, construct: 2]
Caffeine.Stream
iex> h = "Elixir"
iex> t = fn -> sentinel() end
iex> s = construct(h, t)
iex> head(s) == h
true

Like the stream s with the function f applied to each element

Examples

iex> defmodule Natural do
...>   import Caffeine.Stream, only: [construct: 2]
...> 
...>   def stream do
...>     stream(0)
...>   end
...> 
...>   defp stream(n) do
...>     rest = fn -> stream(increment(n)) end
...>     construct(n, rest)
...>   end
...> 
...>   defp increment(n) do
...>     n + 1
...>   end
...> end
iex> Natural.stream()
...> |> Caffeine.Stream.map(&Integer.to_string/1)
...> |> Caffeine.Stream.take(5)
["0","1","2","3","4"]
Link to this function sentinel()
sentinel() :: []

This signals the end of a stream

Don’t count on sentinel/0 returning a []. SoE: how can we do this with a Dialyzer declaration?

Link to this function sentinel?(s)
sentinel?(t()) :: boolean()

Predicate: is s the sentinel?

Examples

iex> import Caffeine.Stream, only: [sentinel?: 1, sentinel: 0, construct: 2]
Caffeine.Stream
iex> sentinel?(sentinel())
true
iex> sentinel?(construct("Elixir", fn -> sentinel() end))
false
Link to this function tail(s)
tail(t()) :: t()

The tail, if any, of the stream s

The following always holds true tail(construct(X, Y)) == Y.().

Examples

iex> import Caffeine.Stream, only: [tail: 1, sentinel: 0, construct: 2]
Caffeine.Stream
iex> h = "Elixir"
iex> t = fn -> sentinel() end
iex> s = construct(h, t)
iex> tail(s) == sentinel()
true
Link to this function take(s, n)
take(t(), integer()) :: list()

A list of n consecutive elements from the stream s

Examples

iex> defmodule Natural do
...>   import Caffeine.Stream, only: [construct: 2]
...> 
...>   def stream do
...>     stream(0)
...>   end
...> 
...>   defp stream(n) do
...>     rest = fn -> stream(increment(n)) end
...>     construct(n, rest)
...>   end
...> 
...>   defp increment(n) do
...>     n + 1
...>   end
...> end
iex> Caffeine.Stream.take(Natural.stream(), 5)
[0,1,2,3,4]