Prev: 恒等モナド TOC: 目次 Next: Error モナド

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

Prev: 恒等モナド TOC: 目次 Next: Error モナド