=
is not assignment in Elixir. More like an assertion.- Succeeds if it can find a way of making left side equal to right side.
a = 1 #1
a + 3 #1
In thise cases the lef side is a variable and right side is an integer literal. So to make the match it binds the variable to the integer.
a = 1 #1
1 = a #1
2 = a # (MatchError) no match of right hand side value: 1
2 = a
raises an error. Elixir only changes left hand side of the =
list = [ 1, 2, 3] # [1, 2, 3]
Elixir bound the variable list
to [1, 2, 3]
Example where a list of variables gets bound to values:
list = [1, 2, 3] # [1, 2, 3]
[a, b, c] = list # [1, 2, 3]
a # 1
b # 2
c # 3
list = [1, 2, [3, 4, 5] ]
# [1, 2, [3, 4, 5]]
[a, b, c] = list
# [1, 2, [3, 4, 5]]
a # 1
b # 2
c # [3, 4, 5]
In this example the literal 2 in the pattern matched the corresponding term on the right so the match succeeds by setting the values of a
and b
to 1 and 3.
list = [1, 2, 3]
#[1, 2, 3]
[a, 2, b] = list
#[1, 2, 3]
a #1
b #3
In the second attempted match, the second term (1) cannot be matched against the corresponding element on the right side (2) so no variales are set and the match fails.
list = [1, 2, 3]
# [1, 2, 3]
[a, 1, b] = list
** (MatchError) no match of right hand side value: [1, 2, 3]
You can use the _
to ignore a value during the match. Acts as a variable but discards any value given to it. Basically a wildcard.
[1, _, _] = [1, 2, 3]
# [1, 2, 3]
[1, _, _] = [1, "cat", "dog"]
# [1, "cat", "dog"]
First expression works because a
is matched with the first 1 on the right side. The value in a
then used in the second term to match the second 1 on the right.
[a, a] = [1, 1]
# [1, 1]
a #1
In this expression the first b
matches the 1 but the second b
corresponds to 2 on the right. b
cannot have two different values so fails.
[b, b] = [1, 2]
**(MatchError) no match of right hand side value: [1, 2]
But you can bind a variable to a new value in a subsequent match:
a = 1 #1
[1, a, 3] = [1, 2, 3]
# [1, 2, 3]
a # 2
You can force Elixir to use the existing value of the variable in the pattern with a ^
(the pin operator).
a = 1 #1
a = 2 #2
^a = 1
** (Match Error) no match of right hand side value: 1
a = 1 #1
[^a, 2, 3] = [1, 2, 3]
# [1, 2, 3]
a = 2 #2
[^a, 2] = [1, 2]
** (MatchError) no match of right hand side value: [1, 2]