TaggedTuple (TaggedTuple v1.0.0) View Source
A library to work with tagged tuples.
Tagged tuple is a tuple attaching a tag to a value {tag, value}
.
Common tagged tuples are {:ok, value}
and {:error, message}
returned
from the functions.
Tag chains
A chain of tags can be attached to a single core value by nesting tagged tuples in each other.
For example, {:units, {:boxes, 1}}
and {:units, {:kilograms, 2.5}}
tagged tuples describe the same deliverable item with different measures.
The tag chains of :units
- :boxes
and :units
- :kilograms
can be efficiently pattern matched then to handle core values of
different types appropriately.
Link to this section Summary
Functions
Defines a tagged tuple. It's equivalent to {tag, value}
.
Converts a list to a tagged tuple.
Converts a map to a tagged tuple.
Returns the tag chain and the core value from the given tagged tuple.
Returns a tagged tuple by attaching the tag chain to the core value.
Converts a tagged tuple to a list.
Converts a tagged tuple to a map.
Same as untag!/2
.
Removes the given subchain from the tag chain's beginning and return the tagged tuple built from the rest. When the full tag chain is given, it returns the core value.
Link to this section Functions
Defines a tagged tuple. It's equivalent to {tag, value}
.
The operator is right-associative. When it's called several times in a row, it assembles a tag chain with a value in the core.
:x --- :y --- :z --- "value" == {:x, {:y, {:z, "value"}}}
Can be used in Expressions and Pattern Matchings.
Examples
iex> use TaggedTuple
...> :tag --- 12
{:tag, 12}
...> tagged_tuple = :a --- :tag --- :chain --- 12
{:a, {:tag, {:chain, 12}}}
...> match?(:a --- :tag --- _tail, tagged_tuple)
true
...> :a --- t1 --- t2 --- core_value = tagged_tuple
...> t1 == :tag
...> t2 == :chain
...> core_value == 12
from_list(list, tag_fun \\ fn x -> x end, value_fun \\ fn y -> y end)
View SourceConverts a list to a tagged tuple.
The list must have at least two elements, a tag and a value, respectfully.
The tag_fun
will be invoked with each tag, and the result will be added
to the tuple. The value_fun
will be invoked with the core value, and
the result will be added to the tuple.
Examples
iex> TaggedTuple.from_list([:a, :tag, :chain, 2])
{:a, {:tag, {:chain, 2}}}
iex> TaggedTuple.from_list(["a", "tag", "chain", 200], &String.to_existing_atom/1, &div(&1, 100))
{:a, {:tag, {:chain, 2}}}
from_map(map, tag_fun \\ fn x -> x end, value_fun \\ fn y -> y end)
View SourceConverts a map to a tagged tuple.
The tag_fun
will be invoked with each tag, and the result will be added
to the tuple. The value_fun
will be invoked with the core value,
and the result will be added to the tuple.
Examples
iex> TaggedTuple.from_map(%{a: %{tag: %{chain: 2}}})
{:a, {:tag, {:chain, 2}}}
iex> TaggedTuple.from_map(%{"a" => %{"tag" => %{"chain" => 20}}}, &String.to_existing_atom/1, &div(&1, 10))
{:a, {:tag, {:chain, 2}}}
Returns the tag chain and the core value from the given tagged tuple.
Examples
iex> {chain, value} = TaggedTuple.split({:a, {:tag, {:chain, 2}}})
...> chain == {:a, {:tag, :chain}}
...> value == 2
iex> TaggedTuple.tag(value, chain)
{:a, {:tag, {:chain, 2}}}
Returns a tagged tuple by attaching the tag chain to the core value.
tag_chain
can be a nested tuple with tags returned from the split/1
or a list with tags.
Example
iex> TaggedTuple.tag(2.5, :some_tag)
{:some_tag, 2.5}
iex> TaggedTuple.tag(7, {:a, {:tag, :chain}})
{:a, {:tag, {:chain, 7}}}
iex> TaggedTuple.tag(7, [:a, :tag, :chain])
{:a, {:tag, {:chain, 7}}}
to_list(tagged_tuple, tag_fun \\ fn x -> x end, value_fun \\ fn y -> y end)
View SourceConverts a tagged tuple to a list.
The tag_fun
will be invoked with each tag, and the result will be inserted
into the list. The value_fun
will be invoked with the tagged tuple's
core value, and the result will be inserted into the list.
Examples
iex> TaggedTuple.to_list({:a, {:tag, {:chain, 2}}})
[:a, :tag, :chain, 2]
iex> TaggedTuple.to_list({:a, {:tag, {:chain, 2}}}, &to_string/1, &(&1 * 100))
["a", "tag", "chain", 200]
to_map(tagged_tuple, tag_fun \\ fn x -> x end, value_fun \\ fn y -> y end)
View SourceConverts a tagged tuple to a map.
The returned map can be encoded into a JSON to transmit over the network or persist in a database.
The tag_fun
will be invoked with each tag, and the result will be inserted
into the map. The value_fun
will be invoked with the tagged tuple's
core value, and the result will be inserted into the map.
Examples
iex> TaggedTuple.to_map({:a, {:tag, {:chain, 2}}})
%{a: %{tag: %{chain: 2}}}
iex> TaggedTuple.to_map({:a, {:tag, {:chain, 2}}}, &to_string/1, &(&1 * 100))
%{"a" => %{"tag" => %{"chain" => 200}}}
Same as untag!/2
.
Returns {:error, :mismatch}
when tag_chain
doesn't match
the beginning part of the tag chain of the tagged tuple.
Removes the given subchain from the tag chain's beginning and return the tagged tuple built from the rest. When the full tag chain is given, it returns the core value.
Raises ArgumentError
exception if the passed tag subchain doesn't match
the begginning of the tag chain of the tagged tuple.
tag_chain
can be a nested tuple with tags returned from the split/1
or a list with tags.
Examples
iex> value = {:a, {:tag, {:chain, 2}}}
iex> TaggedTuple.untag!(value, :a)
{:tag, {:chain, 2}}
iex> TaggedTuple.untag!(value, {:a, :tag})
{:chain, 2}
iex> TaggedTuple.untag!(value, {:a, {:tag, :chain}})
2
iex> TaggedTuple.untag!(value, [:a, :tag, :chain])
2
iex> value = {:other, {:stuff, 2}}
...> TaggedTuple.untag!(value, {:a, {:tag, :chain}})
** (ArgumentError) Tag chain {:a, {:tag, :chain}} doesn't match one in the tagged tuple {:other, {:stuff, 2}}.