パート10までやってきた自分えらい
ガード
- 引数の構造で場合分け
- パターンマッチを使う
- 引数の値が満たす性質で場合分け
- ガードを使う
例
bmiTell :: Double -> String bmiTell bmi | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedly normal. Pfffft, I bet you're ugly!" | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!"
実行
*Main> bmiTell 24.3 "You're supposedly normal. Pfffft, I bet you're ugly!" *Main> bmiTell 1 "You're underweight, you emo, you!" *Main> bmiTell 100 "You're a whale, congratulations!"
| <真偽値式> = <関数本体>
*if/else
使うよりガード使えとのことotherwise
でその他のパターンを拾う
その他の例
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> max' 1 3 3 *Main> 1 `myCompare` 3 LT
where
- 計算の途中結果に名前を付けることができる
- ガードの後に書く
bmiTell' :: Double -> Double -> String bmiTell' weight height | bmi <= 18.5 = "You're underweight, you emo, you!" | bmi <= 25.0 = "You're supposedly normal. Pfffft, I bet you're ugly!" | bmi <= 30.0 = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2
もうちょっと修正
bmiTell' :: Double -> Double -> String bmiTell' weight height | bmi <= skinny = "You're underweight, you emo, you!" | bmi <= normal = "You're supposedly normal. Pfffft, I bet you're ugly!" | bmi <= fat = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2 skinny = 18.5 normal = 25.0 fat = 30.0
where ブロック内のインデントは揃えないと正しく動かない
where のスコープ
動かない例
greet :: String -> String greet "Juan" = niceGreeting ++ " Juan!" greet "Fernando" = niceGreeting ++ " Fernando!" greet name = badGreeting ++ " " ++ name where niceGreeting = "Hello! So very nice to see you," badGreeting = "Oh! Pffft. It's you."
この書き方だと、where で束縛された変数は最後の関数の本体からしか見えない。
greet name = ...
の部分。そしてコンパイル時に怒られる。
*Main> :l src/chapter3.hs [1 of 1] Compiling Main ( src/chapter3.hs, interpreted ) src/chapter3.hs:56:16: error: Variable not in scope: niceGreeting :: [Char] src/chapter3.hs:57:20: error: Variable not in scope: niceGreeting :: [Char] Failed, modules loaded: none.
動く例
badGreeting :: String badGreeting = "Oh! Pffft. It's you." niceGreeting :: String niceGreeting = "Hello! So very nice to see you," greet :: String -> String greet "Juan" = niceGreeting ++ " Juan!" greet "Fernando" = niceGreeting ++ " Fernando!" greet name = badGreeting ++ " " ++ name
こんな感じで関数の外で定義してあげないと参照できない
*Main> greet "Juan" "Hello! So very nice to see you, Juan!" *Main> greet "tokoyax" "Oh! Pffft. It's you. tokoyax"
where の中でパターンマッチ
initials :: String -> String initials firstname lastname = [f] ++ ". " ++ [l] ++ "." where (f:_) = firstname (l:_) = lastname
where の中で関数定義
calcBmis :: [(Double), (Double)] -> [Double] calcBmis xs = [bmi w h | (w, h) <- xs] where bmi weight height = weight / height ^ 2
今日はここまで

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る