View Source Iter.Impl (iterex v0.1.2)
The default implementations of all Iter.Iterable callbacks except next/1.
By adding use Iter.Impl to your Iter.Iterable definition all of the
default functions will be automatically delegated and marked as overridable.
This allows you to implement only those callbacks which can reasonably be made faster for your particular iterable, and not have to implement all of them.
For example, here's a fictional implementation of iterable for List:
defimpl Iter.Iterable, for: List do
use Iter.Impl
def next([head | tail]), do: {:ok, head, tail}
def next([]), do: :done
def peek([]), do: :done
def peek([head | _] = list), do: {:ok, head, list}
def empty?([]), do: true
def empty?(_), do: false
endBe aware that all the default implementations rely on your implementation of
next/1 which you always must provide.
Summary
Functions
Generate overridable delegations to the default iterable callbacks.
Tests if every element in the iterable matches predicate.
Tests if any element in the iterable matches predicate.
Creates an iterable that appends an element to the end of the iterable.
Returns the element index items from the beginning of the iterable.
Creates an iterable that chunks elements by subsequent return values of fun.
Creates an iterable that chunks elements into count sized chunks of step spacing.
Creates an iterable that chunks based on a chunk function.
Takes an iterable and iterates each iterable in an iterable.
Consumes the iterable, returning the number of elements within
Consumes the iterable, returning the number of elements for which fun returns a truthy value.
Creates an iterator that cycles it's elements eternally.
Creates an iterable that only emits elements if they are different from the previous element.
Creates an iterable that only emits elements if they are different from the previous element.
Creates an iterable which drops the first how_many elements.
Returns a new iterable with every nth element in the iterable dropped,
starting with the first element.
Drops elements at the beginning of iterable while fun returns a truthy
value.
Consumes the iterable and applies fun to each element.
Determines if the iterable is empty.
Creates an iterable which drops elements for which predicate doesn't return true.
Searches for the first element in the iterable which matches predicate.
Returns the index of the first element in the iterable which matches predicate.
Returns the first truthy value returned by fun.
Creates an iterable which works like map/2 but flattens nested iterables.
Creates an iterable which flattens nested iterables.
Creates a new iterable which places separator between adjacent items of the original iterable.
Creates a new iterable which applies mapper to each element and using it's
result as the new element value.
Creates a new iterable which applies mapper on every nth element of the
iterable, starting with the first element.
Returns the maximal element in the iterable according to Erlang's term ordering.
Returns the maximal element in the iterable as calculated by mapper.
Is the element a member of the iterable?
Returns the minimal element in the iterable according to Erlang's term ordering.
Returns the minimal element in the iterable as calculated by mapper.
Finds the minimal and maximal elements in the iterable.
Peeks at the first element of the iterable, without consuming it.
Peeks at the first how_many elements of the iterable, without consuming them.
Creates a new iterable which places element at the beginning of the iterable.
Creates an iterable starting at the same point, but stepping by how_many each iteration.
Collects the first how_many elements into a new iterable and returns it
along with the advanced initial iterable.
Creates an iterable which takes the first how_many elements.
Creates an iterable which takes the last how_many elements.
Creates an iterable which emits elements until predicate returns false.
Convert the iterable into a list.
Creates an iterable that only emits unique elements.
Creates an iterable which emits the current iteration count as well as the next value.
Zips corresponding elements from a finite collection of iterables into one iterable of results as computed by zipper.
Types
@type element() :: Iter.Iterable.element()
@type iterable() :: Iter.Iterable.t()
@type predicate() :: Iter.Iterable.predicate()
Functions
Generate overridable delegations to the default iterable callbacks.
Tests if every element in the iterable matches predicate.
Examples
iex> Impl.all?([2, 4, 6, 8], &(rem(&1, 2) == 0))
true
iex> Impl.all?([2, 3, 4], &(rem(&1, 2) == 0))
false
Tests if any element in the iterable matches predicate.
Examples
iex> Impl.any?([2, 4, 6], &(rem(&1, 2) == 1))
false
iex> Impl.any?([2, 3, 4], &(rem(&1, 2) == 1))
true
Creates an iterable that appends an element to the end of the iterable.
Examples
iex> Impl.append(1..3, 4)
...> |> Impl.to_list()
[1, 2, 3, 4]
@spec at(iterable(), non_neg_integer()) :: {:ok, element(), iterable()} | :done
Returns the element index items from the beginning of the iterable.
Example
iex> Impl.at([:a, :b, :c], 1)
{:ok, :b, [:c]}
Creates an iterable that chunks elements by subsequent return values of fun.
Example
iex> Impl.chunk_by([1, 2, 2, 3, 4, 4, 6, 7, 7], &(rem(&1, 2) == 1))
...> |> Impl.to_list()
[[1], [2, 2], [3], [4, 4, 6], [7, 7]]
@spec chunk_every(iterable(), pos_integer(), pos_integer(), iterable() | :discard) :: iterable()
Creates an iterable that chunks elements into count sized chunks of step spacing.
Examples
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 2, 2, []) |> Impl.to_list()
[[1, 2], [3, 4], [5, 6]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, :discard) |> Impl.to_list()
[[1, 2, 3], [3, 4, 5]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 2, [7]) |> Impl.to_list()
[[1, 2, 3], [3, 4, 5], [5, 6, 7]]
iex> Impl.chunk_every([1, 2, 3, 4, 5, 6], 3, 3, []) |> Impl.to_list()
[[1, 2, 3], [4, 5, 6]]
iex> cycler = Impl.cycle([0])
iex> Impl.chunk_every([1, 2, 3, 4], 3, 3, cycler) |> Impl.to_list()
[[1, 2, 3], [4, 0, 0]]
@spec chunk_while( iterable(), acc, (element(), acc -> {:cont, chunk, acc} | {:cont, acc} | {:halt, acc}), (acc -> {:cont, chunk, acc} | {:cont, acc}) ) :: iterable() when acc: any(), chunk: any()
Creates an iterable that chunks based on a chunk function.
Examples
iex> chunk_fun = fn element, acc ->
...> if rem(element, 2) == 0 do
...> {:cont, Enum.reverse([element | acc]), []}
...> else
...> {:cont, [element | acc]}
...> end
...> end
iex> after_fun = fn
...> [] -> {:cont, []}
...> acc -> {:cont, Enum.reverse(acc), []}
...> end
iex> iter = 1..10 |> Impl.chunk_while([], chunk_fun, after_fun)
iex> Impl.to_list(iter)
[[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
Takes an iterable and iterates each iterable in an iterable.
Example
iex> Impl.concat([1..3, 2..4, 3..5]) |> Impl.to_list()
[1, 2, 3, 2, 3, 4, 3, 4, 5]
@spec count(iterable()) :: non_neg_integer()
Consumes the iterable, returning the number of elements within
Examples
iex> Impl.count([])
0
iex> Impl.count([1,2,3])
3
@spec count(iterable(), (element() -> as_boolean(any()))) :: non_neg_integer()
Consumes the iterable, returning the number of elements for which fun returns a truthy value.
Example
iex> 1..5
...> |> Impl.count(&(rem(&1, 2) == 0))
2
Creates an iterator that cycles it's elements eternally.
Example
iex> Impl.cycle(1..3)
...> |> Impl.take_head(5)
...> |> Impl.to_list()
[1, 2, 3, 1, 2]
Creates an iterable that only emits elements if they are different from the previous element.
Example
iex> Impl.dedup([:a, :a, :b, :c, :b, :c, :c, :d])
...> |> Impl.to_list()
[:a, :b, :c, :b, :c, :d]
Creates an iterable that only emits elements if they are different from the previous element.
The function fun maps every element to a term which is used to determine if two elements are duplicates.
Example
iex> [{1, :a}, {2, :b}, {2, :c}, {1, :a}]
...> |> Impl.dedup_by(&elem(&1, 0))
...> |> Impl.to_list()
[{1, :a}, {2, :b}, {1, :a}]
@spec drop(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which drops the first how_many elements.
Examples
iex> Impl.drop([1, 2, 3], 2)
...> |> Impl.to_list()
[3]
iex> Impl.drop([1, 2, 3], 0)
...> |> Impl.to_list()
[1, 2, 3]
iex> Impl.drop([1, 2, 3], -2)
...> |> Impl.to_list()
[1]
@spec drop_every(iterable(), non_neg_integer()) :: iterable()
Returns a new iterable with every nth element in the iterable dropped,
starting with the first element.
Examples
iex> 1..10
...> |> Impl.drop_every(2)
...> |> Impl.to_list()
[2, 4, 6, 8, 10]
iex> 1..12
...> |> Impl.drop_every(3)
...> |> Impl.to_list()
[2, 3, 5, 6, 8, 9, 11, 12]
iex> 1..10
...> |> Impl.drop_every(0)
...> |> Impl.to_list()
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
iex> [1, 2, 3]
...> |> Impl.drop_every(1)
...> |> Impl.to_list()
[]
Drops elements at the beginning of iterable while fun returns a truthy
value.
Example
iex> [1, 2, 3, 2, 1]
...> |> Impl.drop_while(&(&1 < 3))
...> |> Impl.to_list()
[3, 2, 1]
Consumes the iterable and applies fun to each element.
Primarily used for side-effects.
Always returns :done.
Example
Impl.each([1, 2, 3], &IO.puts("#{&1}"))
"1"
"2"
"3"
#=> :done
Determines if the iterable is empty.
Example
iex> Impl.empty?([])
true
iex> Impl.empty?(1..20)
false
Creates an iterable which drops elements for which predicate doesn't return true.
Example
iex> Impl.filter([1, 2, 3, 4], &(rem(&1, 2) == 1))
...> |> Impl.to_list()
[1, 3]
Searches for the first element in the iterable which matches predicate.
Example
iex> Impl.find([1, 2, 3, 4], &(&1 > 2))
{:ok, 3, [4]}
iex> Impl.find([1, 2, 3, 4], &(&1 > 4))
:done
@spec find_index(iterable(), predicate()) :: {:ok, non_neg_integer(), iterable()} | :done
Returns the index of the first element in the iterable which matches predicate.
Examples
iex> Impl.find_index([1, 2, 3, 4], &(&1 > 2))
{:ok, 2, [4]}
iex> Impl.find_index([1, 2, 3, 4], &(&1 > 4))
:done
@spec find_value(iterable(), (element() -> result)) :: {:ok, result, iterable()} | :done when result: any()
Returns the first truthy value returned by fun.
Example
iex> Impl.find_value([1, 2, 3, 4], fn
...> i when i > 2 -> i * 2
...> _ -> nil
...> end)
{:ok, 6, [4]}
Creates an iterable which works like map/2 but flattens nested iterables.
Example
iex> [:a, :b, :c]
...> |> Impl.flat_map(&[&1, &1])
...> |> Impl.to_list()
[:a, :a, :b, :b, :c, :c]
Creates an iterable which flattens nested iterables.
Example
iex> Impl.flatten([[1, 2], [3, [4, [5, 6]]]])
...> |> Impl.to_list()
[1, 2, 3, 4, 5, 6]
Creates a new iterable which places separator between adjacent items of the original iterable.
Example
iex> Impl.intersperse([:a, :b, :c], :wat)
...> |> Impl.to_list()
[:a, :wat, :b, :wat, :c]
Creates a new iterable which applies mapper to each element and using it's
result as the new element value.
Example
iex> Impl.map([1, 2, 3], &(&1 * &1))
...> |> Impl.to_list()
[1, 4, 9]
@spec map_every(iterable(), non_neg_integer(), (element() -> new_element)) :: iterable() when new_element: any()
Creates a new iterable which applies mapper on every nth element of the
iterable, starting with the first element.
The first element is always mapped unless nth is 0.
Examples
iex> Impl.map_every(1..10, 2, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 2, 1003, 4, 1005, 6, 1007, 8, 1009, 10]
iex> Impl.map_every(1..10, 3, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 2, 3, 1004, 5, 6, 1007, 8, 9, 1010]
iex> Impl.map_every(1..5, 0, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1, 2, 3, 4, 5]
iex> Impl.map_every([1, 2, 3], 1, fn x -> x + 1000 end)
...> |> Impl.to_list()
[1001, 1002, 1003]
Returns the maximal element in the iterable according to Erlang's term ordering.
Examples
iex> Impl.max([1, 3, 2], &>=/2)
{:ok, 3}
iex> Impl.max([], &>=/2)
:done
@spec max_by( iterable(), (element() -> new_element), (new_element, new_element -> boolean()) ) :: {:ok, element()} | :done when new_element: element()
Returns the maximal element in the iterable as calculated by mapper.
Example
iex> Impl.max_by(["a", "aa", "aaa"], &String.length/1, &>=/2)
{:ok, "aaa"}
iex> Impl.max_by([], &String.length/1, &>=/2)
:done
Is the element a member of the iterable?
Returns the minimal element in the iterable according to Erlang's term ordering.
Examples
iex> Impl.min([1, 3, 2], &<=/2)
{:ok, 1}
iex> Impl.min([], &<=/2)
:done
@spec min_by( iterable(), (element() -> new_element), (new_element, new_element -> boolean()) ) :: {:ok, element()} | :done when new_element: element()
Returns the minimal element in the iterable as calculated by mapper.
Example
iex> Impl.min_by(["a", "aa", "aaa"], &String.length/1, &<=/2)
{:ok, "a"}
iex> Impl.min_by([], &String.length/1, &<=/2)
:done
Finds the minimal and maximal elements in the iterable.
Example
iex> Impl.min_max(1..12)
{:ok, 1, 12}
iex> Impl.min_max([])
:done
Peeks at the first element of the iterable, without consuming it.
Warning
Many iterables cannot be peeked, so this function simulates peeking by consuming an element from the iterable and returning a new iterable which pushes that element back on to the front.
Example
iex> {:ok, :a, iterable} = Impl.peek([:a, :b, :c])
...> Impl.to_list(iterable)
[:a, :b, :c]
@spec peek(iterable(), how_many :: pos_integer()) :: {:ok, [element()], non_neg_integer(), iterable()} | :done
Peeks at the first how_many elements of the iterable, without consuming them.
Warning
Many iterables cannot be peeked, so this function simulates peeking by consuming elements from the iterable and returning a new iterable which pushes those elements back on to the front.
Example
iex> {:ok, [:a, :b, :c], 3, iterable} = Impl.peek([:a, :b, :c, :d], 3)
...> Impl.to_list(iterable)
[:a, :b, :c, :d]
Creates a new iterable which places element at the beginning of the iterable.
Example
iex> 1..5
...> |> Impl.prepend(6)
...> |> Impl.to_list()
[6, 1, 2, 3, 4, 5]
@spec step_by(iterable(), non_neg_integer()) :: iterable()
Creates an iterable starting at the same point, but stepping by how_many each iteration.
Example
iex> [0, 1, 2, 3, 4, 5]
...> |> Impl.step_by(2)
...> |> Impl.to_list()
[0, 2, 4]
@spec take_chunk(iterable(), pos_integer()) :: {:ok, iterable(), iterable()} | {:done, iterable()}
Collects the first how_many elements into a new iterable and returns it
along with the advanced initial iterable.
This is very much like take/2 except that it returns the remaining iterable
so that it can be called repeatedly.
Example
iex> iter = 1..9
...> {:ok, [1, 2, 3], iter} = Impl.take_chunk(iter, 3)
...> {:ok, [4, 5, 6], iter} = Impl.take_chunk(iter, 3)
...> Impl.to_list(iter)
[7, 8, 9]
@spec take_head(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which takes the first how_many elements.
Example
iex> Impl.take_head(1..5, 0)
...> |> Impl.to_list()
[]
iex> Impl.take_head(1..5, 3)
...> |> Impl.to_list()
[1, 2, 3]
@spec take_tail(iterable(), non_neg_integer()) :: iterable()
Creates an iterable which takes the last how_many elements.
Example
iex> Impl.take_tail(1..5, 0)
...> |> Impl.to_list()
[]
iex> Impl.take_tail(1..5, 3)
...> |> Impl.to_list()
[3, 4, 5]
Creates an iterable which emits elements until predicate returns false.
Example
iex> [1, 2, 3]
...> |> Impl.take_while(&(&1 < 3))
...> |> Impl.to_list()
[1, 2]
Convert the iterable into a list.
Creates an iterable that only emits unique elements.
Example
iex> Impl.uniq([:a, :a, :b, :c, :b, :c, :c, :d])
...> |> Impl.to_list()
[:a, :b, :c, :d]
Creates an iterable which emits the current iteration count as well as the next value.
This is analogous to Enum.with_index/1 except that counting starts from the
beginning of the iterable, meaning you can convert an iterable into an
enumerator after consuming some if it.
Examples
iex> Impl.with_index([:a, :b, :c]) ...> |> Impl.to_list() [a: 0, b: 1, c: 2]
iex> [:a, :b, :c, :d] ...> |> Impl.drop(2) ...> |> Impl.with_index() ...> |> Impl.to_list() [c: 0, d: 1]
Zips corresponding elements from a finite collection of iterables into one iterable of results as computed by zipper.
Example
iex> Impl.zip([1..3, 4..6, 7..9], &List.to_tuple/1) ...> |> Impl.to_list() [{1, 4, 7}, {2, 5, 8}, {3, 6, 9}]