Monads which allow their actions to be run in
IO.
While
MonadIO allows an
IO action to be lifted into
another monad, this class captures the opposite concept: allowing you
to capture the monadic context. Note that, in order to meet the laws
given below, the intuition is that a monad must have no monadic state,
but may have monadic context. This essentially limits
MonadUnliftIO to
ReaderT and
IdentityT
transformers on top of
IO.
Laws. For any function
run provided by
withRunInIO, it
must meet the monad transformer laws as reformulated for
MonadUnliftIO:
Instances of
MonadUnliftIO must also satisfy the following
laws:
- Identity law withRunInIO (\run -> run m) =
m
- Inverse law withRunInIO (\_ -> m) = liftIO
m
As an example of an invalid instance, a naive implementation of
MonadUnliftIO (StateT s m) might be
withRunInIO inner =
StateT $ \s ->
withRunInIO $ \run ->
inner (run . flip evalStateT s)
This breaks the identity law because the inner
run m would
throw away any state changes in
m.