スポンサーリンク

2015年8月4日

[Elixir]パターンマッチの基本を習得する

とある錬金術師の万能薬(Elixir)

Goal

Elixirのパターンマッチングを習得する。

Dev-Environment

OS: Windows8.1
Erlang: Eshell V6.4, OTP-Version 17.5
Elixir: v1.0.4

Wait a minute

基本的なパターンマッチを見ていきましょう。

Index

Pattern match
|> The match operator
|> Pattern matching
|> The pin operator
|> Extra

The match operator

マッチ演算子について。
軽くまとめ・・・
  • =演算子はマッチ演算子
  • 変数は、=の左側にあるときだけ束縛できる
  • マッチしないとMatchErrorが発生
  • 変数は再束縛できる
iex(1)> x = 1
1
iex(2)> x
1
iex(3)> 1 = x
1
iex(4)> 2 = x
** (MatchError) no match of right hand side value: 1

iex(5)> x = 2
2

Pattern matching

本題のパターンマッチについて。
軽くまとめ
  • 複雑なデータ型にも使える
  • 両側の対応が必要
  • サイズや型が異なるとできない
  • 左側に関数呼び出しは使えない
タプルで使ってみる。
iex(1)> {a,b,c} = {:hello, "world", 1}
{:hello, "world", 1}
iex(2)> {:hello, "world", 1} = {a,b,c}
{:hello, "world", 1}
iex(3)> {:hello, "world", 2} = {a,b,c}
** (MatchError) no match of right hand side value: {:hello, "world", 1}

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

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

iex(7)> {:ok, result} = {:ok, 1}
{:ok, 1}
iex(8)> result
1
リストで使ってみる。
iex(1)> [a, b, c] = [1, 2, 3]
[1, 2, 3]
iex(2)> a
1
iex(3)> b
2
iex(4)> c
3
iex(5)> [head | tail] = [1, 2, 3]
[1, 2, 3]
iex(6)> head
1
iex(7)> tail
[2, 3]
iex(8)> [head | tail] = []
** (MatchError) no match of right hand side value: []

iex(8)> list = [1, 2, 3]
[1, 2, 3]
iex(9)> [0 | list]
[0, 1, 2, 3]
Description:
リストだとheadとtailが使える。

The pin operator

ピン演算子について。
軽くまとめ・・・
  • パターンの値を制限する場合、^(キャレット)を使って束縛する
  • パターンの値を制限しない場合、_(アンダースコア)へ束縛する
^(キャレット)を試す。
iex(1)> x = 1
1
iex(2)> ^x = 2
** (MatchError) no match of right hand side value: 2

iex(2)> ^x = 1
1
iex(3)> {x, ^x} = {2, 1}
{2, 1}
iex(4)> x
2
iex(5)> ^x
** (CompileError) iex:14: cannot use ^x outside of match clauses

iex(5)> {x, x} = {1, 1}
{1, 1}
iex(6)> {x, x} = {1, 2}
** (MatchError) no match of right hand side value: {1, 2}
_(アンダースコア)を試す。
iex(1)> [h | _] = [1, 2, 3]
[1, 2, 3]
iex(2)> h
1
iex(3)> _
** (CompileError) iex:17: unbound variable _

Extra

パターンマッチのちょっとした応用。
PhoenixFrameworkを使っていると、よく見ると思いますが。
mapに対して部分的にマッチさせることができる。
iex(1)> params = %{"a" => 1, "b" => 2, "c" => 3}
%{"a" => 1, "b" => 2, "c" => 3}
iex(2)> params["b"]
2
iex(3)> %{"b" => d} = params
%{"a" => 1, "b" => 2, "c" => 3}
iex(4)> d
2
何ができるの?って話ですが、
以下のようなことができるようになる。
def hoget(%{"hoge" => hoge}) do
  ...
end

params = %{"hoge" => :hoge, "huge" => :huge}
hoget(params)

Speaking to oneself

昼寝したせいで、頭が重い・・・
パターンマッチを使えば色々できます。
以上・・・

Bibliography

人気の投稿