Maybe モナド
概観
計算のタイプ: |
Nothing を返す可能性のある計算 |
束縛戦略: |
Nothing 値は束縛された関数をバイパスし、それ以外の値
は束縛された関数への入力として使われる
|
利用場面: |
Nothing を返すかもしれない関数のならびから計算を
構築する。複雑なデータベースへの問い合わせ、あるいは辞書の検索などが
よい例です。
|
ゼロとプラス: |
Nothing がゼロ。プラス演算子は最初の
非-Nothing 値を返すか、両方の入力が Nothing
であった場合には、Nothing を返す。
|
型の例: |
Maybe a |
動機
Maybe モナドは計算の連鎖を合成する戦略を内包している。それぞれの計算が
それまでのどのステップも出力として Nothing
となれば、
最後に Nothing を返すかもしれない。これは計算が、互いに
依存するステップの並びを伴い、その中に値を返すのを失敗するかもしれない
ステップが含まれている場合に役にたちます。
もし以下のようなコードを書いたことがあるなら:
case ... of
Nothing -> Nothing
Just x -> case ... of
Nothing -> Nothing
Just y -> ...
Maybe
のモナドとしての性質をつかってコードを改良することを
考えるべきでしょう。
定義
data Maybe a = Nothing | Just a
instance Monad Maybe where
return = Just
fail = Nothing
Nothing >>= f = Nothing
(Just x) >>= f = f x
instance MonadPlus Maybe where
mzero = Nothing
Nothing `mplus` x = x
x `mplus` _ = x
|
例
よく使われる例は辞書の検索です。フルネームを Email アドレスに
写像する辞書があり、もうひとつニックネームを Email アドレスに
写像する辞書があり、さらにみっつめとして Email アドレスを好みの
email の形式に写像する辞書があるとしましょう。フルネームあるいは
ニックネームのどちらかを基に個人の好みの Email の形式を見い出す
関数をつくることができます。
example11.hs
で使えるコード |
data MailPref = HTML | Plain
data MailSystem = ...
getMailPrefs :: MailSystem -> String -> Maybe MailPref
getMailPrefs sys name =
do let nameDB = fullNameDB sys
nickDB = nickNameDB sys
prefDB = prefsDB sys
addr <- (lookup name nameDB) `mplus` (lookup name nickDB)
lookup addr prefDB
|