Once a variable has been bound to a value in the matching process, it keeps that value for the remainder of the match.
| iex> [a, a] = [1, 1] |
| [1, 1] |
| iex> a |
| 1 |
| iex> [b, b] = [1, 2] |
| ** (MatchError) no match of right hand side value: [1, 2] |
The first expression in this example succeeds because a is initially matched with the first 1 on the right side. The value in a is then used in the second term to match the second 1 on the right side.
In the next expression, the first b matches the 1. But the second b corresponds to the value 2 on the right. b cannot have two different values, and so the match fails.
However, a variable can be bound to a new value in a subsequent match, and its current value does not participate in the new match.
| iex> a = 1 |
| 1 |
| iex> [1, a, 3] = [1, 2, 3] |
| [1, 2, 3] |
| iex> a |
| 2 |
What if you instead want to force Elixir to use the existing value of the variable in the pattern? Prefix it with ^ (a caret). In Elixir, we call this the pin operator.
| iex> a = 1 |
| 1 |
| iex> a = 2 |
| 2 |
| iex> ^a = 1 |
| ** (MatchError) no match of right hand side value: 1 |
This also works if the variable is a component of a pattern:
| iex> a = 1 |
| 1 |
| iex> [^a, 2, 3 ] = [ 1, 2, 3 ] # use existing value of a |
| [1, 2, 3] |
| iex> a = 2 |
| 2 |
| iex> [ ^a, 2 ] = [ 1, 2 ] |
| ** (MatchError) no match of right hand side value: [1, 2] |
There’s one more important part of pattern matching, which we’ll look at when we start digging deeper into lists.