In Elixir, if I try to pattern match the following two tuples:
{a} = {1, 2}
I get a match error. But if I do the same for two maps:
<
maps
, the main key-value store in Elixir, have an interesting capability that sets them apart from other data structures with regards to pattern-matching.
A map
can actually pattern-match on just a subset of a value. The key(s) in the pattern have to exist in the match, but the two structures don’t have to mirror each other in the same way a list
or a tuple
has to. For example:
iex(1)> [a, b] = [1, 2, 3]
** (MatchError) no match of right hand side value: [1, 2, 3]
iex(1)> {a, b} = {1, 2, 3}
** (MatchError) no match of right hand side value: {1, 2, 3}
iex(1)> %{:a => one} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(2)> one
1
iex(3)> %{:a => one, :c => three} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(4)> three
3
iex(5)> one
1
iex(6)> %{} = %{:a => 1, :b => 2, :c =>3}
%{a: 1, b: 2, c: 3}
iex(7)> %{:d => four} = %{:a => 1, :b => 2, :c =>3}
** (MatchError) no match of right hand side value: %{a: 1, b: 2, c: 3}
iex(8)> %{:a => one, :d => four} = %{:a => 1, :b => 2, :c =>3}
** (MatchError) no match of right hand side value: %{a: 1, b: 2, c: 3}
We can see that neither the list
nor the tuple
matches if the data structure of the pattern is different to the data structure of the match, namely the size. Whereas this is not the case for the map. Because the key is present in both the pattern and the match then the match is successful, regardless of the different sizes of the pattern and the match. An empty map
will also match.
However the match will not be successful if the key in the pattern is not in the match. This is also the case even if there are matching keys. So any key used in the pattern has to be present in the match.
You will see this sort of matching extensively in Phoenix Framework to pick up only the necessary params from request.
Source: - Notes on Elixir: Pattern-Matching Maps