fugafuga.write

日々のログ

すごいH本 part84

ピエールを落とす

バナナを仕掛けてピエールを問答無用で落とす関数を作る

banana :: Pole -> Maybe Pole
banana _ = Nothing

これを一連の関数の中に混ぜて使う

*Main> return (0, 0) >>= landLeft 1 >>= banana >>= landRight 1
Nothing

落ちた。

入力に関係なく規定のモナド値を返す関数を作りたい場合、>>を使うとよい。

(>>) :: (Monad m) => m a -> m b -> m b
m >> n = m >>= \_ -> n

実行

*Main> Nothing >> Just 3
Nothing
*Main> Just 3 >> Just 4
Just 4
*Main> Just 3 >> Nothing
Nothing

1番目の例が既定値のJust 3を返さず、Nothingを返しているのは、 Nothing >>= \_ -> Just 3 となっているため。

*Main> Nothing >>= \_ -> Just 3
Nothing

このことから、banana関数は、>> Nothingで置き換えることができる。

*Main> return (0, 0) >>= landLeft 1 >> Nothing >>= landRight 1
Nothing

仮にMaybeによる文脈を使わずに一連の処理を書こうとすると次のようになる。

routine :: Maybe Pole
routine = case landLeft 1 (0, 0) of
    Nothing -> Nothing
    Just pole1 -> case landRight 4 pole1 of
        Nothing -> Nothing
        Just pole2 -> case landLeft 2 pole2 of
            Nothing -> Nothing
            Just pole3 -> landLeft 1 pole3

失敗しているかどうか検査する度に分岐が発生している。 このようなコードが発生する場合に、Maybeモナドが有用である。

Maybeモナドの >>= の実装は、値がNothingかどうかを判定し、その知識に基いて動作を変える というロジックになっている。

所感

Maybeモナドが失敗するかも知れないという文脈を抽象化してくれているおかげで、 一連の処理の定義がシンプルになっていることがわかった。

ただ、モナドはこれだけでは終わらんのであろう。