パターンマッチング

 cf. 4 パターンマッチング – Pattern matching – Elixir

マッチ演算子

= は変数への束縛に使われる。

iex(1)> x = 1
1
iex(2)> x
1

けれども、Elixir では = はマッチ演算子と呼ばれる。なぜなら、本質的には左辺と右辺のマッチングに使われるから。変数への束縛は、変数が左辺にあって右辺とマッチした時にだけ起こる。

iex(3)> 1 = x
1
iex(4)> 2 = x
** (MatchError) no match of right hand side value: 1

1 = x という式が Elixir では妥当な式であることに注意(何の役に立つのかわからないけど)。2つ目の例では左辺と右辺がマッチしないのでエラーが起きている。

パターンマッチング

マッチ演算子はもっと複雑なデータにも使える。例えばタプルにも。

iex(5)> {a, b, c} = {1, 2, 3}
{1, 2, 3}
iex(6)> a
1
iex(7)> b
2
iex(8)> c
3

このパターンマッチングは左辺と右辺が対応していないとエラーになる。タプルのサイズが違うとか、異なるデータ型だとかいう場合だ。

iex(9)> {a, b, c} = {:hello, "world"}
** (MatchError) no match of right hand side value: {:hello, "world"}

iex(9)> {a, b, c} = [1, 2, 3]
** (MatchError) no match of right hand side value: [1, 2, 3]

特定の値にマッチさせることもできる。次の例では、タプルの最初の値が :ok の時だけマッチする。

iex(9)> {:ok, result} = {:ok, "hello"}
{:ok, "hello"}
iex(10)> result
"hello"
iex(11)> {:ok, result} = {:error, "hello"}
** (MatchError) no match of right hand side value: {:error, "hello"}

リストでは headtail というパターンマッチができる。

iex(11)> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex(12)> head
1
iex(13)> tail
[2, 3]

ちょっと話題がずれるけど、この [head|tail] という形式は、リストの先頭に値を追加するのにも使える。

iex(14)> list = [1, 2, 3]
[1, 2, 3]
iex(15)> [0 | list]
[0, 1, 2, 3]

ピン演算子

Elixir の変数は再束縛することができる。

iex(16)> x = 1
1
iex(17)> x = 2
2
iex(18)> x
2

ピン演算子 ^ は、束縛済みの値とマッチングさせたいときに使う。

iex(19)> x = 1
1
iex(20)> ^x = 2
** (MatchError) no match of right hand side value: 2

パターンの中の値が何でもいい時には _ にマッチさせる。

iex(20)> {x, _, y} = {1, 2, 3}
{1, 2, 3}
iex(21)> x
1
iex(22)> y
3

今日はここまで。