- 上から順にマッチする
- この場合、3は一番下にたどり着かない
- 一番最後に入力すべてに合致するパタンを入れておいた方がよい
lucky :: Int -> String
lucky 7 = "LUCKY NUMBER SEVEN!!"
lucky x = "Sorry, you're out of luck, pal!"
lucky 3 = "LUCKY NUMBER THREE!"
- _は予約語
- _の代わりに(x, x, z)とすると構文エラーになる
third :: (a, b, c) -> c
third (_, _, z) = z
firstLetter :: String -> String
firstLetter "" = "Empty string, whoops!"
firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x]
- 引数の構造はパターンマッチ、値はガードで分ける
- otherwiseはワイルドカード、なくてもエラーにならない
- すべてのガードにマッチししなかった場合、次のパターンマッチに移る
- いずれのパターンマッチにも合致しなかった場合エラーになる
bmiTell :: Double -> String
bmiTell bmi
| bmi <= 18.5 = "You' re underweight, you emo, you!"
| bmi <= 25.0 = "You' re supposedly normal.\
\ Pffft, I bet you're ugly!"
| bmi <= 30.0 = "You're fat! Lose some wieght, fatty!"
| otherwise = "You're a whale, congraturations!"
- 関数内でだけ、変数や関数を定義する
- where内でパターンマッチが可能
bmiTell'' :: Double -> Double -> String
bmiTell'' weight height
| bmi <= skinny = "You're underweight, you emo, you!"
| bmi <= normal = "You're supposedly normal.\
\ Pffft, I bet you're ugly!"
| bmi <= fat = "You're fat! Lose some wieght, fatty!"
| otherwise = "You're a whale, congraturations!"
where
bmi = weight / height ^ 2
(skinny, normal, fat) = (18.5, 25.0, 30.0)
- 異なる関数から利用するにはグローバルに定義する必要がある
where関係無くね?
niceGreeting :: String
niceGreeting = "Hello! So very nice to see you,"
- whereの様に変数や関数を定義する 式
- whereとは記載順が逆(定義が前)
- スコープがwhereより狭い
cylinder :: Double -> Double -> Double
cylinder r h =
let sideArea = 2 * pi * r * h
topArea = pi * r ^ 2
in sideArea + 2 * topArea
4 * (let a = 9 in a + 1) + 2
calcBmis :: [(Double, Double)] -> [Double]
calcBmis xs = [bmi | (w, h) <- xs, let bmi = w / h ^ 2]
- case 式 なので、評価した値をそのまま使える
- パターンマッチもできる
describeList :: [Char] -> String
describeList ls = "The list is "
++ case ls of [] -> "empty."
"A" -> "The A."
[x] -> "a singleton list."
xs -> "a longer list."