モナド
モナドは強化されたアプリカティブファンクターである。
モナドはある願いを叶えるための、アプリカティブ値の自然な拡張である。
願いとは、
普通の値 a を取って文脈付きの値を返す関数に、文脈付きの値 m a を渡したい
というもの。
言い換えると、a -> m b
型の関数を、m a
型の値に適用したい。ということ。
(>>=) :: (Monad m) => m a -> (a -> m b) -> m b
つまり、この関数が使いたい。
関数>>=
はバインド(bind)
と呼ばれる。
文脈付きの値を普通の値をとる関数に入力するのにはどうしたらいいのか? これがモナドの一番の関心事である。
Maybe から始めるモナド
Maybe a 型の値は a 型の値を表しているが、失敗する可能性があるという文脈がついている。
ファンクター値としての Maybe に対して fmap すると以下のようになる。
*Main Lib> fmap (++"!") (Just "wisdom") Just "wisdom!" *Main Lib> fmap (++"!") Nothing Nothing
アプリカティブファンクターとしての Maybe の機能も似たようなもの。 しかし、値だけでなく、適用する関数のほうにも文脈が付く。
*Main Lib> Just (+3) <*> Just 5 Just 8 *Main Lib> Nothing <*> Just "greed" Nothing
Maybe にとっての >>=
をどう定義するのか。
*Main Lib> (\x -> Just (x+1)) 1 Just 2 *Main Lib> (\x -> Just (x+1)) 100 Just 101
数をとり、それに1を足して Just で包む。1 を入力して、Just 2 に評価されている。 この関数に Maybe 値を入力するにはどうしたらよいか考える。
これは、Maybe がアプリカティブファンクターとしての振る舞いができることから、 Just 値が来たときは、Just の中身を取り出し、それを関数に渡す。 Nothing が来た時は、結果として Nothing を返す。
>>=
を applyMaybe
という関数で実装してみる
applyMaybe :: Maybe a -> (a -> Maybe b) -> Maybe b applyMaybe Nothing f = Nothing applyMaybe (Just x) f = f x
実行
*Main> Just 3 `applyMaybe` \x -> Just (x+1) Just 4 *Main> Just "smile" `applyMaybe` \x -> Just (x ++ " :)") Just "smile :)" *Main> Nothing `applyMaybe` \x -> Just (x+1) Nothing *Main> Nothing `applyMaybe` \x -> Just (x ++ " :)") Nothing
関数の結果が Nothing の場合
*Main> Just 3 `applyMaybe` \x -> if x > 2 then Just x else Nothing Just 3 *Main> Just 1 `applyMaybe` \x -> if x > 2 then Just x else Nothing Nothing
文脈付きの値を普通の値を引数にとる関数に渡すことができている。
Monad 型クラス
class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b x >> y = x >>= \_ -> y fail :: String -> m a fail msg = error msg
return
は Applicative 型クラスの pure
と同じで、
値を取って、その値を再現できるような最小のデフォルト文脈に入れる。
>>=
はバインド。通常の値を取り、モナド値を返す関数を適用して、モナド値を返す。
>>
はデフォルト実装があるので省く。(詳細はあとで見る)
fail
はユーザーがコードの中から fail を呼び出すことはなく、
Haskell システムが呼び出す。
fail はモナド用の特別な構文において、パターンマッチに失敗してもプログラムを異常終了させず、
失敗をモナドの文脈の中で扱えるようにするためのもの。
Maybe の Monad インスタンスの実装をみてゆく
instance Monad Maybe where return x = Just x Nothing >>= f = Nothing Just x >>= f = f x fail _ = Nothing
モナド化したMaybeを見る
*Main> return "hohohoho" :: Maybe String Just "hohohoho" *Main> Just 9 >>= \x -> return (x*10) Just 90 *Main> Nothing >>= \x -> return (x*10) Nothing
所感
これがモナドか。 いまのところよくわからん。

- 作者: MiranLipovaca
- 出版社/メーカー: オーム社
- 発売日: 2017/07/14
- メディア: Kindle版
- 購入: 4人 クリック: 9回
- この商品を含むブログを見る