Elixir:エリクサー~関数の定義方法まとめ

プログラミング言語Elixirの、関数定義の書式をまとめます。

1行で書く、複数行で書く、省略形など、いくつかパターンがあります。

 

 

1行で関数を定義して変数に格納する。

定義
aという引数を取り、aを出力する関数。

iex()> func1 = fn a -> IO.puts a end
#Function<6.99386804/1 in :erl_eval.expr/5>

 

実行

iex()> func1.(1234)
1234
iex()> func1.(:functiontest)
functiontest
:ok

 

関数定義の省略表現

&()で関数を定義できます。

引数は&1、&2、&3…で参照できる。

以下は引数3つの和を返す関数。

iex()> func3 = &(&1+&2+&3)
#Function<18.99386804/3 in :erl_eval.expr/5>

 

実行

iex()> func3.(1,2,3)
6

 

複数行の関数を定義する

複数行の関数を書くとき。1行の時とさして変わらない。

インデントはスペース2つぶんにするのがElixirでは普通らしい。

iex()> func4 = fn name ->
...()> output = "Hello "<>name
...()> IO.puts output
...()> end
#Function<6.99386804/1 in :erl_eval.expr/5>

 

実行。

iex()> func4.("taro")
Hello taro
:ok

 

引数のパターンマッチを利用して処理を分ける

引数のパターンマッチを使って処理を分けるのがElixirらしさ。

これによりif文を書かないようにするのがElixirらしさ。

1つ1つのブロックが小さくなり、コードが美しく保たれる。

 

引数がtaroとjiroの時は「I am taro」という形で出力する。

それ以外は引数をそのまま使って、「Other name:(nameの値)」を出力する。

iex()> func5 = fn
...()> "taro" -> IO.puts "I am taro"
...()> "jiro" -> IO.puts "I am jiro"
...()> name -> IO.puts "Other name:" <> name
...()> end
#Function<6.99386804/1 in :erl_eval.expr/5>

ちなみに、関数の引数のパターンの部分を「ヘッド」と言うらしい。この例では、「3つのヘッドがある」という事になる。 

 

実行結果

iex()> func5.("taro")
I am taro
:ok
iex()> func5.("jiro")
I am jiro
:ok
iex()> func5.("saburo")
Other name:saburo
:ok

 

引数をピン(^ ←これ)で固定する

Elixirにはピン演算子というのがあって、

変数名の頭に「^」を付けると最初にマッチさせた値に変数の内容を固定させることができる。

関数の引数にもこれを使うことが出来る。

 

定義

iex()> func6 = fn
...()> (^name) -> "first call: #{name}"
...()> (_) -> "second call"
...()> end
#Function<6.99386804/1 in :erl_eval.expr/5>

 

実行

iex()> func6.("hoge")
"first call: hoge"
iex()> func6.("piyo")
"second call"
iex()> func6.("hoge")
"first call: hoge"

 最初に"hoge"という値を渡すと、nameの値が"hoge"に固定される。

シングルトンパターン的な使い方できるのだろうか…