|
1 | 1 | defprotocol Enum.Iterator do
|
2 | 2 | @moduledoc """
|
3 | 3 | This is the protocol used by the `Enum` module.
|
4 |
| - Usually, when you invoke a function in the module `Enum`, |
5 |
| - the first argument passed to `Enum` is a collection which |
6 |
| - is forwarded to this protocol in order to retrieve information |
7 |
| - on how to iterate the collection. That said, when: |
| 4 | +
|
| 5 | + Usually, when you invoke a function in the module `Enum`, the first argument |
| 6 | + passed to it is a collection which is forwarded to this protocol in order to |
| 7 | + retrieve information on how to iterate the collection. |
| 8 | +
|
| 9 | + For example, in the expression |
8 | 10 |
|
9 | 11 | Enum.map [1,2,3], &1 * 2
|
10 | 12 |
|
11 |
| - Is invoked, it invokes `Enum.Iterator.iterator([1,2,3])` |
12 |
| - which returns all the information required by Enum. |
13 |
| - Read each function documentation below for more information. |
| 13 | + `Enum.map` invokes `Enum.Iterator.iterator([1,2,3])` to retrieve the iterator |
| 14 | + function that will drive the iteration process. |
14 | 15 | """
|
15 | 16 |
|
16 | 17 | @only [List, Record, Function]
|
17 | 18 |
|
18 | 19 | @doc """
|
19 |
| - Iteration in Elixir happens with the help of a iterator |
20 |
| - function. Every time this function is called, it must |
21 |
| - return a tuple with two elements. The first element |
22 |
| - is the next item and the second can be any Elixir term |
23 |
| - which the function is going to receive as argument the |
24 |
| - next time it is invoked. |
| 20 | + This function must return a tuple of the form `{ iter, step }` where |
| 21 | + `iter` is a function that yields successive values from the collection |
| 22 | + each time it is invoked and `step` is the first step of iteration. |
25 | 23 |
|
26 |
| - When there are no more items to be iterated, the function |
27 |
| - must return the atom `:stop`. |
| 24 | + Iteration in Elixir happens with the help of an _iterator function_ (named |
| 25 | + `iter` in the paragraph above). When it is invoked, it must return a tuple |
| 26 | + with two elements. The first element is the next successive value from the |
| 27 | + collection and the second element can be any Elixir term which `iter` is |
| 28 | + going to receive as its argument the next time it is invoked. |
28 | 29 |
|
29 |
| - In order to retrieve this iterator function, Elixir invokes |
30 |
| - `Enum.Iterator.iterator(collection)` which should return a |
31 |
| - tuple with two elements: the first element is the iterator |
32 |
| - function and the second is the first step of iteration. |
| 30 | + When there are no more items left to yield, `iter` must return the atom |
| 31 | + `:stop`. |
33 | 32 |
|
34 |
| - As an example, here is the implementation of iterator for lists: |
| 33 | + As an example, here is the implementation of `iterator` for lists: |
35 | 34 |
|
36 | 35 | def iterator(list), do: { iterate(&1), iterate(list) }
|
37 | 36 | defp iterate([h|t]), do: { h, t }
|
38 | 37 | defp iterate([]), do: :stop
|
39 | 38 |
|
| 39 | + Here, `iterate` is the _iterator function_ and `{ h, t }` is a step of |
| 40 | + iteration. |
| 41 | +
|
40 | 42 | ## Iterating lists
|
41 | 43 |
|
42 |
| - If a data structure needs to be converted to a list in order |
43 |
| - to be iterated, the iterator function can simply return the |
44 |
| - list and the Enum module will be able to take over the list |
45 |
| - and retrieve the proper iterator function. |
| 44 | + As a special case, if a data structure needs to be converted to a list in |
| 45 | + order to be iterated, `iterator` can simply return the list and the `Enum` |
| 46 | + module will be able to take over the list and produce a proper iterator |
| 47 | + function for it. |
46 | 48 | """
|
47 | 49 | def iterator(collection)
|
48 | 50 |
|
49 | 51 | @doc """
|
50 |
| - The function used to retrieve the collection size. |
| 52 | + The function used to retrieve the collection's size. |
51 | 53 | """
|
52 | 54 | def count(collection)
|
53 | 55 | end
|
|
0 commit comments