前回の続き
Haskell を使ってみる 5 (型) - kntmr-blog
パターンマッチ
パターンマッチは、データ型が従うべきパターンを指定してそのパターンに従ってデータを分解するために使う。
-- パターンマッチと再帰で n の階乗を求める関数 factorial :: Int -> Int factorial 0 = 1 factorial n = n * factorial (n - 1) *Main> factorial 5 120
パターンマッチでパターンに合致しない値を指定するとエラーになる。パターンマッチの最後にすべてに合致するパターンを入れる。
showNumber :: Int -> String showNumber 1 = "One" showNumber 2 = "Two" showNumber 3 = "Three" *Main> showNumber 1 "One" *Main> showNumber 5 -- これはパターンにない "*** Exception: pattern-matching.hs:(6,1)-(8,22): Non-exhaustive patterns in function showNumber
タプルのパターンマッチ
タプルの要素を分解して処理できる。
-- ペアを受け取って足し合わせる関数 addVectors :: (Int, Int) -> (Int, Int) -> (Int, Int) addVectors (x1, y1) (x2, y2) = (x1 + x2, y1 + y2) *Main> addVectors (1, 2) (2, 3) (3,5)
リストのパターンマッチ
リスト内包表記でパターンマッチを使う場合、パターンに合致しないものは処理されない。
Prelude> let xs = [(1,2), (2,3), (2,4), (1,5), (3,6)] Prelude> [x * 100 | (1, x) <- xs] -- 1つ目の要素が1のペアのみ処理される [200,500]
リストのパターンマッチ
リストの先頭3要素を足し合わせる関数。
sumThree :: (Num a) => [a] -> a sumThree [] = 0 sumThree (x:[]) = x sumThree (x:y:[]) = x + y sumThree (x:y:z:[]) = x + y + z sumThree (x:y:z:_) = x + y + z -- この行がないと4要素のリストを指定した場合にエラーになる *Main> sumThree [] 0 *Main> sumThree [1] 1 *Main> sumThree [1, 2] 3 *Main> sumThree [1, 2, 3] 6 *Main> sumThree [1, 2, 3, 4] -- 4つ目の要素は足し合わされない 6
as パターン
as パターンでは、パターンマッチの対象になる値自体を参照することができる。パターンの前に名前と @
を付ける。
firstLetter :: String -> String firstLetter "" = "Emptry string." firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] *Main> firstLetter "" "Emptry string." *Main> firstLetter "Hello" "The first letter of Hello is H"
今回はパターンマッチについて。