A protocol to traverse data structures.
The Enum.into/2 function uses this protocol to insert an
enumerable into a collection:
iex> Enum.into([a: 1, b: 2], %{})
%{a: 1, b: 2}
Why Collectable?
The Enumerable protocol is useful to take values out of a collection.
In order to support a wide range of values, the functions provided by
the Enumerable protocol do not keep shape. For example, passing a
dictionary to Enum.map/2 always returns a list.
This design is intentional. Enumerable was designed to support infinite
collections, resources and other structures with fixed shape. For example,
it doesn't make sense to insert values into a range, as it has a fixed
shape where just the range limits are stored.
The Collectable module was designed to fill the gap left by the
Enumerable protocol. It provides two functions: into/1 and empty/1.
into/1 can be seen as the opposite of Enumerable.reduce/3. If
Enumerable is about taking values out, Collectable.into/1 is about
collecting those values into a structure.