関数を定義する際、引数の構造で場合分けするときにはパターンを使う。
引数の値が満たす性質で場合分けするときはガードを使う。
パターンのときもそうだったが、
これを使いこなせないとif/then/elseを多用することになって可読性が著しく下がる。
ガードの例
式を評価して、Falseなら下へ続く。どれでもないならOtherwise
bmiTell :: Double -> String bmiTell bmi | bmi <= 18.5 = "You're underweight" | bmi <= 25.0 = "You're normal" | bmi <= 30.0 = "You're fat" | otherwise = "You're a whale"
結果
Main> bmiTell 24 "You're normal" Main> bmiTell 1 "You're underweight" Main> bmiTell 28 "You're fat" Main> bmiTell 100.55555 "You're a whale"
なお、全ての式を評価してFalseとなり、なおかつOtherwiseもFalseとなるなら、
「適切なパターンが見つからない」というエラーが返ってくる。
なお、ガードは複数の引数を取る関数にも使える。
bmiTell' :: Double -> Double -> String bmiTell' weight height | weight / height ^ 2 <= 18.5 = "You're underweight" | weight / height ^ 2 <= 25.0 = "You're normal" | weight / height ^ 2 <= 30.0 = "You're fat" | otherwise = "You're a whale" max' :: (Ord a) => a -> a -> a max' a b | a <= b = b | otherwise = a myCompare :: (Ord a) => a -> a -> Ordering a `myCompare` b | a == b = EQ | a <= b = LT | otherwise = GT
結果
Main> bmiTell' 85 1.90 "You're normal" Main> max' 4 300 300 Main> myCompare 4 4 EQ Main> 3 `myCompare` 2 GT