Witchcraft.Traversable (Witchcraft v1.0.4) View Source

Walk through a data structure from left to right, running some action on each element in turn.

Similar to applicatives, it can be used to do things like collecting some effect while performing other actions.

Type Class

An instance of Witchcraft.Traversable must also implement Witchcraft.Foldable and Witchcraft.Functor, and define Witchcraft.Foldable.right_fold/3.

[right_fold/3]  Foldable    Functor  [map/2]
                           
                     Traversable
                   [right_fold/3]

Link to this section Summary

Functions

Run each action/effect in sequence (from left to right), and accumulate values along the way.

traverse/2 with arguments reversed.

Convert elements to actions, and then evaluate the actions from left-to-right, and accumulate the results.

Link to this section Types

Specs

link() :: (any() -> t())

Specs

t() :: any()

Link to this section Functions

Specs

sequence(t()) :: Witchcraft.Foldable.t()

Run each action/effect in sequence (from left to right), and accumulate values along the way.

Examples

iex> sequence([{1, 2, 3}, {4, 5, 6}])
{5, 7, [3, 6]}

iex> [
...>   [1, 2, 3],
...>   [4, 5, 6]
...> ]
...> |> sequence()
[
  [1, 4],
  [1, 5],
  [1, 6],
  [2, 4],
  [2, 5],
  [2, 6],
  [3, 4],
  [3, 5],
  [3, 6]
]
Link to this function

through(link, traversable)

View Source

Specs

through(link(), t()) :: t()

traverse/2 with arguments reversed.

Examples

iex> fn x -> {x, x * 2, x * 10} end |> through([1, 2, 3])
{6, 12, [10, 20, 30]}

iex> fn x -> [x] end |> through({1, 2, 3})
[{1, 2, 3}]

iex> fn x -> [x, x * 5, x * 10] end |> through({1, 2, 3})
[
  {1, 2, 3},
  {1, 2, 15},
  {1, 2, 30}
]

iex> fn x -> [x, x * 5, x * 10] end |> through([1, 2, 3])
[
  #
  [1, 2,  3], [1, 2,  15], [1, 2,  30],
  [1, 10, 3], [1, 10, 15], [1, 10, 30],
  [1, 20, 3], [1, 20, 15], [1, 20, 30],
  #
  [5, 2,  3], [5, 2,  15], [5, 2,  30],
  [5, 10, 3], [5, 10, 15], [5, 10, 30],
  [5, 20, 3], [5, 20, 15], [5, 20, 30],
  #
  [10, 2,  3], [10, 2,  15], [10, 2,  30],
  [10, 10, 3], [10, 10, 15], [10, 10, 30],
  [10, 20, 3], [10, 20, 15], [10, 20, 30]
]

Specs

traverse(t(), link()) :: t()

Convert elements to actions, and then evaluate the actions from left-to-right, and accumulate the results.

For a version without accumulation, see then_traverse/2.

Examples

iex> traverse([1, 2, 3], fn x -> {x, x * 2, x * 10} end)
{6, 12, [10, 20, 30]}

iex> traverse({1, 2, 3}, fn x -> [x] end)
[{1, 2, 3}]

iex> traverse({1, 2, 3}, fn x -> [x, x * 5, x * 10] end)
[
  {1, 2, 3},
  {1, 2, 15},
  {1, 2, 30}
]

iex> traverse([1, 2, 3], fn x -> [x, x * 5, x * 10] end)
[
  #
  [1, 2,  3], [1, 2,  15], [1, 2,  30],
  [1, 10, 3], [1, 10, 15], [1, 10, 30],
  [1, 20, 3], [1, 20, 15], [1, 20, 30],
  #
  [5, 2,  3], [5, 2,  15], [5, 2,  30],
  [5, 10, 3], [5, 10, 15], [5, 10, 30],
  [5, 20, 3], [5, 20, 15], [5, 20, 30],
  #
  [10, 2,  3], [10, 2,  15], [10, 2,  30],
  [10, 10, 3], [10, 10, 15], [10, 10, 30],
  [10, 20, 3], [10, 20, 15], [10, 20, 30]
]

traverse([1, 2, 3], fn x -> %Algae.Maybe.Just{just: x} end)
#=> %Algae.Maybe.Just{just: [1, 2, 3]}

traverse(%Algae.Maybe.Just{just: 4}, fn x -> [x, x * 10] end)
#=> [
#     %Algae.Maybe.Just{just: 4},
#     %Algae.Maybe.Just{just: 40}
#   ]

traverse([1, 2, 3], fn x ->
  if is_even(x) do
    %Algae.Maybe.Just{just: x}
  else
    %Algae.Maybe.Nothing{}
  end
end)
#=> %Algae.Maybe.Nothing{}