仕込み Monad Transformer

[id:yts:20050112#p2]の続き。

ReaderTの特別な場合なので:

module ReaderTick where
import Control.Monad.Reader

type TickT m a = ReaderT (m ()) m a

runTickT :: Monad m => TickT m a -> m () -> m a
runTickT = runReaderT

tick :: Monad m => m a -> TickT m a
tick m = ask >>= lift >> lift m

putStrLn' = tick . putStrLn
signal = putStrLn "!"

test = flip runTickT signal $ 
  do  putStrLn' "one."
      putStrLn' "two."
      putStrLn' "three."
      tick $ putStrLn "four."
      tick $ putStrLn "five."

TickT と名付けるときは tick じゃなくて lift で lift できるようにnewtypeしとくべきかな。