パターンマッチの基本
The match operator
- Elixirにおける
=
はmatch operator
- 代入ではなくパターンマッチにおける束縛を意味する
# これは一見代入しているように見える
iex> x = 1
1
# xに1が束縛された状態で逆にしても通る
iex> 1 = x
1
# これは通らない。1が束縛された x と 2 はマッチしない
iex> 2 = x
** (MatchError) no match of right hand side value: 2
# 左辺がvariableであれば再度束縛される
iex> x = 2
2
# pin operator をつけると防いでくれる
iex> ^x = 3
** (MatchError) no match of right hand side value: 3
# 今は2が束縛されているのでマッチする
iex> 2 = x
2
パターンマッチ
iex> {a, b, c} = {:hello, "world", 42}
{:hello, "world", 42}
iex> a
:hello
iex> b
"world"
iex> c
42
# 逆にしても通る
iex> {:hello, "world", 42} = {a, b, c}
{:hello, "world", 42}
# これはTuple内の要素数が異なるのでマッチしない
iex> {a, b} = {:hello, "world", 42}
# 要素数が同じでも値が異なればマッチしない
iex> {a, b, c} = {:hello, "world", 444}
iex> {:ok, result} = {:ok, "hoge"}
{:ok, "hoge"}
# resultにはhogeが束縛される
iex> result
hoge
# これはtupleの1つめのatomが:ngと:okでマッチしない
iex> {:ng, result} = {:ok, "hoge"}
** (MatchError) no match of right hand side value: {:ok, "hoge"}
iex> [x,y,z] = [1,2,3]
[1, 2, 3]
iex> x
1
iex> y
2
iex> z
3
iex> [1,2,3] = [x,y,z]
[1, 2, 3]
# 他の要素がマッチしていれば束縛も可能
iex> [1, x, 3] = [1, 5, 3]
[1, 5, 3]
# xには5が束縛される
iex> x
5
# Haskellにもあったけど [ head | tail ]のマッチングもできる
iex> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex> head
1
iex> tail
[2, 3]
# 空Listはマッチしない
iex> [head | tail] = []
** (MatchError) no match of right hand side value: []
underscore
- 特別な意味を持つvariableでワイルドカードにおける * のような存在。
- なんにでもマッチするが、上の例で出てきたように _ にマッチした値が束縛されることはない
iex> [1, _, 3] = [1, 2, 3]
[1, 2, 3]
iex> _
** (CompileError) iex:28: unbound variable _
function
iex> 3 = length([1,[2],3])
3
# ただし関数が左辺に来るとできない
iex> length([1,[2],3]) = 3
** (CompileError) iex:1: illegal pattern