Reputation:
I'm familiar with monads, e.g. Reader
, Error
, and State
. Transformers, however, are very new to me, hence this question.
Intuitively, I can tell there is a difference between the following two monad transformers, but I can't quite pinpoint what it is...
ReaderT Env (ErrorT String (StateT Integer Identity)) a
ReaderT Env (StateT Integer (ErrorT String Identity)) a
What makes these two monad transformers different?
Upvotes: 4
Views: 85
Reputation: 116139
ReaderT Env (ErrorT String (StateT Integer Identity)) a
ReaderT Env (StateT Integer (ErrorT String Identity)) a
Briefly put, in the first errors only depend on the Env
input, while the second allows errors to depend on both Env
and the Integer
state.
Upvotes: 1
Reputation: 120711
To simplify, compare only the relevant part (which isn't trivially the same):
MaybeT (StateT Integer Identity) a
StateT Integer (MaybeT Identity) a
We know that (ignoring the newtype
abstractions)
type MaybeT m a = m (Maybe a)
type StateT s m a = s -> m (a, s)
Hence, the two transformer stack come out to be
MaybeT (Λb. Integer -> (b, Integer)) a
≡ Integer -> (Maybe a, Integer)
and
StateT Integer (Λb. Maybe b) a
≡ Integer -> Maybe (a, Integer)
So, these aren't exactly the same, the difference being that the latter only yields the state-integer inside of the Maybe
. This means, if the MaybeT
is down in the stack then the computation must immediately terminate as soon as you get a Nothing
, whereas if the MaybeT
is used on top then the State
can still keep on going.
This is even more drastic with IO
: once you get an exception, you can't possibly continue – exceptions can only be caught in IO
itself. This is one reason why there can be no IOT
transformer.
Upvotes: 5