generated at
ReaderT

haskell
newtype ReaderT r m a = ReaderT { runReaderT :: r -> m a }

ReaderT r m は、計算の中でr型の値を共有するモナドで、 ask :: ReaderT r m r でその値にアクセスできる。値を途中で変更したりすることはできない。一見かなりパッシブで面白みのなさそうなモナドだが、非常に実用性は高い。

ReaderT パターン


StateTやWriterTと違い、ReaderTはforkIOできる。WriterTやStateTの場合は出力された値の行き場がない。無理やり実装したmonad-controlというパッケージもあるが、よろしくない振る舞いをすることになるだろう。

haskell
ReaderT $ \r -> forkIO $ runReaderT m r StateT $ \s -> do tid <- forkIO $ do (a, s') <- runStateT m s  -- s'はどこへ消える? return (tid, s)

また、例外処理とも相性がよく、IORefやTVarなどの参照をReaderTで共有するという設計「ReaderTパターン」は並行プログラミングと非常に相性がよい。これを主軸として作られたunliftioというライブラリではReaderTに対応したAPIが一通り揃っており、それに基づいたP派生としてrioというPrelude代替もある。