たとえば Maybe String から String だけを取り出したい場合。 maybe 関数を使えばよい。
maybe 関数を使わなくても、 getString という関数を定義してパターンマッチを使うことで目的は達成できる。
getString :: Maybe String -> String
getString Nothing = ""
getString (Just v) = v
Maybe String から String にする場合、 Maybe String が Nothing だった場合に備えて、デフォルト値を与える必要がある。 ここではそれを空文字列にしている。
ただパターンマッチするには関数を定義しなければいけないので、 Maybe a から a を取り出すたびに関数を定義するのはうれしくはない。 そこで maybe 関数を使う。
maybe のシグネチャを確認:
:t maybe
maybe :: b -> (a -> b) -> Maybe a -> b
これ Maybe a が Nothing だった場合 b になる、という意味らしい。 Maybe a が Nothing でなかったら (a -> b) 関数に Maybe a を適用した値になる。
つまり、デフォルト値、 (a -> b) する関数、 Maybe a を適用すると Maybe a が Nothing なら デフォルト値を そうでなければ a を (a -> b) した b を返す。
文章にするとよくわからないが実際のコードをみれば簡単です。
defaultCoffee = "Veranda Blend"
myCoffee = Just "Cappuccino"
name = maybe defaultCoffee (\c -> c) myCoffee
name は "Cappuccino" になります。
myCoffee が Nothing だった場合:
defaultCoffee = "Veranda Blend"
myCoffee = Nothing
name = maybe defaultCoffee (\c -> c) myCoffee
name は(でフォルトの)"Veranda Blend" になります。
二番目に適用している (\c -> c) 関数は 恒等関数 id に置きかえられます。
:t id
id :: a -> a
以上をまとめると:
defaultCoffee = "Veranda Blend"
myCoffee = Just "Cappuccino"
name = maybe defaultCoffee id myCoffee
myCoffee' = Nothing
name' = maybe defaultCoffee id myCoffee'
maybe 関数を使うとパターンマッチしないで、Maybe の中身を取り出すことができる(デフォルト値の指定は必要)。
ちなみに、Veranda Blend というのは、軽めのコーヒーでアメリカスタバでは一番普通のコーヒーメニューらしいです。 といってもネットでそういう情報を見かけただけで実際は知りませんが。 starbucks.com のコーヒー紹介ページの Brewed Coffees の先頭に登場するのでたぶんそうなんでしょう。
日本のスターバックスではブレンド(コーヒー)と呼称されているがあれ英語だと Brewed Coffee ということも判明。 最近はもう「本日のコーヒー」とか言わないのね。 いつもホットコーヒーください、といってオーダーすることにしている。