Monad Transformer
Monad Transformer(モナド変換子)とは,複数のモナドを合成するやつのこと.
例えば,ReaderモナドとStateモナドを組み合わせて,グローバル変数と状態を持つモナドを作ることができる.
Reader State モナド
例:rを100回足し合わせる処理
code: mt.hs
import Control.Monad.Reader
import Control.Monad.State
main = do
let
r = 100
res = runState (runReaderT solve r) 0
print res --> (10000,10000)
solve :: ReaderT Int (State Int) Int
solve = do
s <- lift get
r <- ask
lift $ put (s + r)
lift get
solve の中で ask と get put が使えているのがわかる.
モナド変換子ReaderTは2番目に「子モナド」を取るので,Stateを入れることができる.すると Reader Stateモナドができる.Reader StateモナドにrunReaderTをすると,Stateモナドが出てくるので,そこにrunStateをapplyして,最終的な結果(lift get)を取り出している.
Reader Writer Stateモナド
Stateにもモナド変換子StateTがあるので,さらにモナドを入れ子にすることができる.
code: mt.hs
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
main = do
let
r = 100
s = 0
res = runWriter (runStateT (runReaderT solve r) s)
print res
solve :: ReaderT Int (StateT Int (Writer Int)) Int solve = do
s <- lift get
r <- ask
lift $ put (s + r)
lift get
solveの中でask get put に加えてtellが使えているのがわかる.