コラッツ予想がとけたらいいな2

自分の考察を書いていきます。

モナド変換子の練習その2

前回のモナド変換子に、さらにIOを乗せて(敷いて?)みます。
putStrLnとかが使えるようになります。

import Control.Monad.State
import Control.Monad.Trans.Maybe

push :: Show a => a -> StateT [a] (MaybeT IO) ()
push x = do
  xs <- get
  put (x:xs)
  lift $ lift $ putStrLn $ "push " ++ show x

pop :: Show a => StateT [a] (MaybeT IO) a
pop = do
  (x:xs) <- get
  put xs
  lift $ lift $ putStrLn $ "pop " ++ show x
  return x

main = runMaybeT $ (`runStateT` [1,10,100]) $ do
  push 3
  pop
  push 2

実行結果です。

> main
push 3
pop 3
push 2
Just ((),[2,1,10,100])
>

うまくいっていますね。
空のstackにpopした場合は、

> runMaybeT $ (`runStateT` []) $ do { pop; }
Nothing

前回同様、自動的にNothingになりました。

強制的にNothingにする場合は、

  lift $ return Nothing

じゃなくて、(これだと何も起こらない)

  lift $ fail ""

とすれば良いです。