top page > computer > haskell > web_lecture > for_programmer > case.html
更新日:
文責: 重城良国

構文: case式

はじめに

case式を使うとより柔軟な形でのパターンマッチが可能となる。

仮引数部でのパターンマッチ

仮引数の部分でのパターンマッチは関数定義という特殊な場面でのみ使える構文糖だ。case式はより広い範囲をカバーする。仮引数部でのパターンマッチとcase式の関係は「関数定義」と「関数リテラル」の関係と似ている。

safeRecip

仮引数部でのパターンマッチは略記法だ。脱糖し関数リテラルとcase式で表現する。

safeRecip 0 = Nothing
safeRecip x = Just $ 1 / x

関数リテラルとcase式によって書き直す。

safeRecip = \x -> case x of
0 -> Nothing
_ -> Just $ 1 / x

うえの表現はしたの表現の構文糖による書き換えと考えられる。

case式の構文

case [式0] of
[パターン1] -> [式1]
[パターン2] -> [式2]
...

式0のところには単純な変数だけでなく複雑な式も置ける。仮引数部を使ったパターンマッチよりも自由に書ける。

レイアウトルール再び

Haskellではレイアウトルールにより明示的な{}や;を省略できる。兄弟要素の列挙はインデントをそろえる。[パターン1], [パターン2], ...は並列の要素なのでインデントをそろえる。並列の要素内で複数行にわけるときはインデントを深くする。

case式でないと書きにくい例

小文字に直したときに'y'か'n'かそれ以外かをチェックする関数を考える。

checkAnswer.hs

checkAnswer :: Char -> Maybe Bool
checkAnswer c = case toLower c of
'y' -> Just True
'n' -> Just False
_ -> Nothing

引数に対して関数を適用したうえでのパターンマッチは仮引数部でのパターンマッチでは簡単には書けない。

case式にもガードを

ガードは真偽値へのパターンマッチに対する構文糖だ。ガードは関数にだけでなくcase式にもつけられる。関数diffRecipは差の逆数を求める例だ。

diffRecip.hs

diffRecip :: Double -> Double -> Maybe Double
diffRecip x y = case x - y of
0 -> Nothing
d | d > 0 -> Just $ recip d
| otherwise -> Just $ recip (- d)

-> [式]の代わりに| [真偽値] -> [式]を必要なだけ置く。

case式にもwhere節を

意味はないが

関数を定義する。

nonsense :: String -> [(String, Int)] -> String
nonsense k d = case lookup k d of
Just n -> s ++ reverse s
where s = show n
_ -> "NO VALUE"

case式のJust nにたいするパターンマッチにwhere節をつけた。

case_where.hs

まとめ

関数の仮引数部分でのパターンマッチは構文糖だ。case式はより広い範囲に適用できる。

case [式0] of
[パターン1] -> [式1]
[パターン2] -> [式2]
...

case式にもガードをつけられる。'-> [式]'の代わりに'| [真偽値] -> [式]'を必要なだけ置く。

課題

  1. 5で割った余りが0ならば5をそれ以外ならば余りの値を返す関数oneToFiveを作成せよ

「構文: where節」へもどる 「if式」へ

正当なCSSです! HTML5 Powered with CSS3 / styling, and Semantics