モナドスタックのスタックの順番
結論: 最終的に欲しい物に依る
得られる結果のノリが変わる
処理自体は同じ
例
code:hs
-- ReaderT
-- ErrorT
-- StateT
-- Identity
type Eval4 a = ReaderT Env (ErrorT String (StateT Integer Identity)) a
runEval4 :: Env -> Integer -> Eval4 a -> (Either String a, Integer)
runEval4 env st ev = runIdentity (runStateT (runErrorT (runReaderT ev env)) st)
戻り値の型を見ると(Either String a, Integer)
(A, s)の形はStateモナドによるもの
この例では実行回数を状態として保持するIntegerが状態の型
AはEitherモナドになっている
Either String a
これはErrorモナドによるもの
Stringがエラーメッセージ
aは結果
結局(エラーかどうか, 実行回数)を返す
エラーの場合はエラーメッセージと実行回数
そうでない場合は結果と実行回数
を返す
つまり、エラーが起ころうが起こらまいが実行回数は絶対得られる
順番を入れ替えたもの
code:hs
-- ReaderT
-- StateT
-- ErrorT
-- Identity
type Eval4' a = ReaderT Env (StateT Integer (ErrorT String Identity)) a
runEval4' :: Env -> Integer -> Eval4' a -> (Either String (a, Integer))
runEval4' env st ev = runIdentity (runErrorT (runStateT (runReaderT ev env) st))
返り値を見ると(Either String (a, Integer))
Either String Bの形をしている
これはErrorモナドによるもので、Stringはエラーメッセージ
Bの(a, Integer)はStateモナドによるもの
結果と実行回数
結局エラーかどうかを返す
エラーならエラーメッセージ
エラーでなければ、「結果と実行回数」
を返す
つまり、エラーが起こったときは実行回数は得られない