3章

- 作者: Fred Hebert
- 出版社/メーカー: オーム社
- 発売日: 2014/08/11
- メディア: Kindle版
- この商品を含むブログ (1件) を見る
3.1 パターンマッチ
defmodule Test do def greet(:male, name), do: IO.puts "Hello, Mr.#{name}!" def greet(:female, name), do: IO.puts "Hello, Mrs.#{name}!" def greet(_, name), do: IO.puts "Hello, #{name}!" end Test.greet :male, "Jack" Test.greet :female, "Betty" Test.greet :foo, "bar"
http://play.elixirbyexample.com/s/efd791c8ab
ちょっとこったパターンマッチ
defmodule Functions do def head([h|_]), do: h def second([_,x|_]), do: x end IO.puts Functions.head [1,2,3,4] IO.puts Functions.second [1,2,3,4]
http://play.elixirbyexample.com/s/439c796408
束縛する変数
- パターンマッチの一つ限界
- 問題解決としてガードを使う
defmodule Functions do def valid_time({date={y,m,d}, time={h,min,s}}) do IO.puts "The Date tuple #{inspect date} says today is: #{y}/#{m}/#{d}" IO.puts "The time tuple #{inspect time} indicates: #{h}:#{min}:#{s}" end def valid_time(_), do: IO.puts "Stop feeding me wrong data!" end IO.puts Functions.valid_time({{2013,12,12},{09,04,43}}) IO.puts Functions.valid_time({{2013,12,12},{09,04}})
http://play.elixirbyexample.com/s/e26faf7eaf
3.2 ガードだ、ガード
- ガード式の基本的なルールは成功時にtrueを返す
- ガード式には数学的な演算やデータ型に対する関数(is_atom/1など)が使えるが、ユーザ定義の関数を受けいれない
ErlangVMではガードで使える式に制限があります:
- 比較演算子(==,!=,===,!==,>,<,<=,>=)
- 論理演算子(and,or)と否定演算子(not,!)
- 算術演算子(+,-,*,/)
- 左側がリテラルの場合の<>と++
- in演算子
以下の全ての型チェック関数: - is_atom/1
- is_binary/1
- is_bitstring/1
- is_boolean/1
- is_float/1
- is_function/1
- is_function/2
- is_integer/1
- is_list/1
- is_map/1
- is_number/1
- is_pid/1
- is_port/1
- is_reference/1
- is_tuple/1
それに加えてこれらの関数: - abs(number)
- bit_size(bitstring)
- byte_size(bitstring)
- div(integer, integer)
- elem(tuple, n)
- hd(list)
- length(list)
- map_size(map)
- node()
- node(pid | ref | port)
- rem(integer, integer)
- round(number)
- self()
- tl(list)
- trunc(number)
- tuple_size(tuple)
5 case,condそしてif - case, cond and if - Elixir
defmodule Functions do def right_age(x) when x >= 16 and x <= 104, do: true def right_age(_), do: false def wrong_age(x) when x < 16 or x > 104, do: true def wrong_age(_), do: false end IO.puts Functions.right_age 20 IO.puts Functions.right_age 105 IO.puts Functions.right_age 14 IO.puts Functions.wrong_age 20 IO.puts Functions.wrong_age 105 IO.puts Functions.wrong_age 14
http://play.elixirbyexample.com/s/b719f280b4
3.3 ifってなんだ?!
- Elixirではマッチしなくてもエラーとならない
defmodule What_the_if do def oh_god(n) do if n === 2 do :might_succeed else :always_does end end end IO.puts What_the_if.oh_god 2 IO.puts What_the_if.oh_god 1
http://play.elixirbyexample.com/s/bf319b9d04
複数のガードを使う場合はcase
がいいっぽい。
defmodule What_the_if do def help_me(animal) do talk = case animal do :cat -> "meow" :beef -> "mooo" :dog -> "bark" :tree -> "bark" _ -> "fgdadfgna" end "#{animal}, sys #{talk}!" end end IO.puts What_the_if.help_me :cat IO.puts What_the_if.help_me :beef IO.puts What_the_if.help_me :dog IO.puts What_the_if.help_me :tree IO.puts What_the_if.help_me :foo
http://play.elixirbyexample.com/s/6e33bf967c
3.4 もしも・・の場合
defmodule What_the_if do def beach(temperature) do case temperature do {:celsius, n} when n >= 20 and n <= 45 -> "favorable" {:kelvin, n} when n >= 293 and n <= 318 -> "scientifically favorite" {:fahrenheit, n} when n >= 68 and n <= 113 -> "favorite in the US" _ -> "avoid beach" end end end IO.puts What_the_if.beach {:celsius, 40} IO.puts What_the_if.beach {:celsius, 46} IO.puts What_the_if.beach {:kelvin, 294} IO.puts What_the_if.beach {:kelvin, 319} IO.puts What_the_if.beach {:fahrenheit, 69} IO.puts What_the_if.beach {:fahrenheit, 114}
http://play.elixirbyexample.com/s/3b94d571cb
他にもcond
がある。
5 case,condそしてif - case, cond and if - Elixir
iex> cond do ...> 2 + 2 == 5 -> ...> "This will not be true" ...> 2 * 2 == 3 -> ...> "Nor this" ...> 1 + 1 == 2 -> ...> "But this will" ...> end "But this will"
これは命令型言語のelse if句と同じです(それらより使う機会は少ないですが).