case 式を使うと、変数の指定した値に対するコードブロックを評価できる。
つまり、コード中のどこでもパターンマッチが使える構文ということである。
関数のパターンマッチ
Haskell では関数のパターンマッチを以下の様に実装する。
例として、リストの先頭要素を取得する関数 head
を実装してみる。
head' :: [a] -> a
head' [] = error "no head"
head' (x:_) = x
case式によるパターンマッチ
関数のパターンマッチは実際には case 式によるパターンマッチのシンタックスシュガーである。
同様に head
の実装は以下のようになる。
head' : [a] -> a
head' xs = case xs of [] -> error "no head"
(x:_) -> x
guardも使える
main :: IO ()
main = do
print $ flip map [1..100] $ \ n -> case n of
n' | n' `mod` 15 == 0 -> "FizzBuzz"
| n' `mod` 5 == 0 -> "Buzz"
| n' `mod` 3 == 0 -> "Fizz"
| otherwise -> show n'
case式はプログラム中のどこでも使える
関数のパターンマッチは関数を定義する際のみだが、case式は式の途中やプログラム中でも使える。
関数の途中で
describeList :: [a] -> String
describeList list = "The list is "
++ case list of [] -> "empty"
[x] -> "a single"
xs -> "multiple"
プログラム中で
case-expression.hs
import System.Environment
import System.IO
main = do
args <- getArgs
let result = case args of [] -> "args is empty"
xs -> foldl (\acc x -> acc ++ x) "args is " xs
putStrLn result
$ ghc --make /path/to/case-expression.hs
$ /path/to/case-expression aaa bbb ccc
args is aaa bbb ccc
$ /path/to/case-expression
args is empty