View Source Iterable protocol (Dsv v0.2.1)

Protocol used to iterate over elements of the iterable. This protocol is used in Dsv.Any, Dsv.All and Dsv.None validators.

The first parameter is the data we want to go through. The second is the functions that receives one element of the iterable at a time and return one of the value:

  • :cont - the iteration should be continue
  • :done - the iteration should be halt immediately

There are default implementations for: List, BitString and Tuple.

BitString implementation goes through graphemes:

iex> Iterable.iterate("Hello! Dzień dobry!", :cont, fn elem -> if elem == "D", do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate("Hello! Dzień dobry!", :cont, fn elem -> if elem == "e", do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate("Hello! Dzień dobry!", :cont, fn elem -> if elem == "h", do: :halt, else: :cont end)
{:done, :empty}

List implementation goes through all elements of the list:

iex> Iterable.iterate(["a", :b, ["c"], %{d: "d"}], :cont, fn elem -> if elem == ["c"], do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate(["a", :b, ["c"], %{d: "d"}], :cont, fn elem -> if elem == %{d: "d"}, do: :halt, else: :cont end)
{:done, :not_empty}

Tuple implementation goes throught all elements of the tuple:

iex> Iterable.iterate({"a", :b, ["c"], %{d: "d"}}, :cont, fn elem -> if elem == ["c"], do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate({"a", :b, ["c"], %{d: "d"}}, :cont, fn elem -> if elem == %{d: "d"}, do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate({:a, :b, :c}, :cont, fn elem -> if elem == :d, do: :halt, else: :cont end)
{:done, :empty}

Map implementation goes throught all elements of the map:

iex> Iterable.iterate(%{a: :b, c: :d}, :cont, fn {_key, value} -> if value == :d, do: :halt, else: :cont end)
{:done, :not_empty}

iex> Iterable.iterate(%{a: :b, c: :d}, :cont, fn {_key, value} -> if value == :e, do: :halt, else: :cont end)
{:done, :empty}

iex> Iterable.iterate(%{}, :cont, fn {_key, value} -> if value == :e, do: :halt, else: :cont end)
{:done, :empty}

Summary

Types

The value for each step.

The next function

The result value for iterate function.

t()

All the types that implement this protocol.

It must be a value that is one of the following "tags"

Functions

Go through every element and provide that element to the next/0 function.

Types

@type element() :: any()

The value for each step.

@type next() :: (current_element :: element() -> tag())

The next function

@type result() :: {:done, :empty} | {:done, :not_empty}

The result value for iterate function.

@type t() :: term()

All the types that implement this protocol.

@type tag() :: :cont | :halt

It must be a value that is one of the following "tags":

  • :cont - the iteration should continue
  • :halt - the iteration should halt immediately

Functions

@spec iterate(t(), tag(), next()) :: result()

Go through every element and provide that element to the next/0 function.