✏️
[Haskell]:条件分岐
🔷 if式
if-then-else
で条件分岐を行うことができる。
🔸 特徴
- ▫️ 他のプログラミング言語のように
else
を省略することはできない。 - ▫️ 入れ子構造(
else if
に似た形)にすることで、複数の条件分岐を行うことができる。
🔸 例
describeNumber:: Int -> String
describeNumber x =
if x < 0
then "負の数"
else if x == 0
then "ゼロ"
else if x `mod` 2 == 0
then "正の偶数"
else
"正の奇数"
以下のように他の言語のようにelse
を省略することはできない。
main :: IO()
main = do
let x = 10
if x `mod` 2 == 0
then print "偶数"
-- エラー:elseを省略することはできない。
🔷 case式
他のプログラミング言語のswitch
文に似たような機能を持つ。
値を指定したパターンを比較して、マッチしたパターンに応じた処理をするパターンマッチング
を行うことができる。
🔸 特徴
- ▫️ 式として値を返すことができる。
- ▫️ ワイルドカードのパターンとして
_
を使用できる。(switch
文のdefault
に相当) - ▫️ ガード構文を使用することで条件付きマッチングを行うことができる。
🔸 例 : 基本的なcase式
describeDirection :: String -> String
describeDirection dir = case dir of
"北" -> "北を向いています"
"南" -> "南を向いています"
"東" -> "東を向いています"
"西" -> "西を向いています"
_ -> "有効な方角ではありません"
🔸 例 : ガードを使ったcase式
describeDigitCount :: Int -> String
describeDigitCount n = case n of
n | n < 0 -> "負"
| n < 10 -> "1桁"
| n < 100 -> "2桁"
| n < 1000 -> "3桁"
| n < 10000 -> "4桁"
| otherwise -> "5桁以上"
🔷 パターンマッチング
関数定義を複数のパターンで記述することにより、引数の値に応じて処理を分岐させることができる。
🔸 特徴
- ▫️ 引数に変数名(例:x)を指定した場合、 任意の値にマッチし、その値を関数内で使用することができる。
- ▫️ 引数に固定値(例:1)を指定した場合、その値のみにマッチする。
- ▫️ 引数にワイルドカード(_)を指定した場合、任意の値にマッチするが、値を関数内で使用することができない。
- ▫️ 上から順に評価され、最初にマッチしたパターンで処理が実行される。
🔸 例
describeDirection :: String -> String
describeDirection "北" = "北を向いています"
describeDirection "南" = "南を向いています"
describeDirection "東" = "東を向いています"
describeDirection "西" = "西を向いています"
describeDirection direction = "「" ++ direction ++ "」は有効な方角ではありません"
-- ワイルドカードの場合は、関数内で値は使えない。
-- describeDirection _ = "有効な方角ではありません"
🔷 ガード
複数の条件判定を優先度順に定義して、処理を分岐させることができる。
🔸 特徴
- ▫️ 複数の条件を定義して、処理を分岐できる。
- ▫️ otherwiseによって、任意の条件にマッチする。
- ▫️ 上から順番に条件が評価されて、最初にマッチした条件で処理が行われる。
- ▫️ パターンマッチングと一緒に使用することができる。
🔸 例 : 基本的なガード
describeDigitCount :: Int -> String
describeDigitCount n
| n < 0 = "負"
| n < 10 = "1桁"
| n < 100 = "2桁"
| n < 1000 = "3桁"
| n < 10000 = "4桁"
| otherwise = "5桁以上"
🔸 例 : パターンマッチングとの組み合わせ
describeDigitCount :: Int -> String
describeDigitCount n | n < 0 = show n ++ "は負の数です"
describeDigitCount n | n < 10 = show n ++ "は1桁です"
describeDigitCount n | n < 100 = show n ++ "は2桁です"
describeDigitCount n | n < 1000 = show n ++ "は3桁です"
describeDigitCount n | n < 10000 = show n ++ "は4桁です"
describeDigitCount n = show n ++ "は5桁以上です"
-- または
describeDigitCount :: Int -> String
describeDigitCount n
| n < 0 = show n ++ "は負の数です"
| n < 10 = show n ++ "は1桁です"
| n < 100 = show n ++ "は2桁です"
| n < 1000 = show n ++ "は3桁です"
| n < 10000 = show n ++ "は4桁です"
| otherwise = show n ++ "は5桁以上です"
🔷 参考
Discussion