generated at
モナドスタックのスタックの順番
モナド変換子モナドスタックのスタックの順番
結論: 最終的に欲しい物に依る
これの2.4のNOTEに書いてあった
得られる結果のノリが変わる
処理自体は同じ


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は結果
結局 (エラーかどうか, 実行回数) を返す
エラーの場合はエラーメッセージと実行回数
そうでない場合は結果と実行回数
を返す
つまり、エラーが起ころうが起こらまいが実行回数は絶対得られる


順番を入れ替えたもの
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モナドによるもの
結果と実行回数
結局 エラーかどうか を返す
エラーならエラーメッセージ
エラーでなければ、「結果と実行回数」
を返す
つまり、エラーが起こったときは実行回数は得られない