unliftio-core- The MonadUnliftIO typeclass for unlifting monads to IO

Safe HaskellSafe



Please see the README.md file for information on using this package at https://www.stackage.org/package/unliftio-core.



class MonadIO m => MonadUnliftIO m where Source #

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 value u returned by askUnliftIO, it must meet the monad transformer laws as reformulated for MonadUnliftIO:

  • unliftIO u . return = return
  • unliftIO u (m >>= f) = unliftIO u m >>= unliftIO u . f

Instances of MonadUnliftIO must also satisfy the idempotency law:

  • askUnliftIO >>= \u -> (liftIO . unliftIO u) m = m

This law showcases two properties. First, askUnliftIO doesn't change the monadic context, and second, liftIO . unliftIO u is equivalent to id IF called in the same monadic context as askUnliftIO.


Minimal complete definition



withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b Source #

Convenience function for capturing the monadic context and running an IO action with a runner function. The runner function is used to run a monadic action m in IO.


MonadUnliftIO IO Source # 
Instance details

Defined in Control.Monad.IO.Unlift


withRunInIO :: ((forall a. IO a -> IO a) -> IO b) -> IO b Source #

MonadUnliftIO m => MonadUnliftIO (IdentityT m) Source # 
Instance details

Defined in Control.Monad.IO.Unlift


withRunInIO :: ((forall a. IdentityT m a -> IO a) -> IO b) -> IdentityT m b Source #

MonadUnliftIO m => MonadUnliftIO (ReaderT r m) Source # 
Instance details

Defined in Control.Monad.IO.Unlift


withRunInIO :: ((forall a. ReaderT r m a -> IO a) -> IO b) -> ReaderT r m b Source #

newtype UnliftIO m Source #

The ability to run any monadic action m a as IO a.

This is more precisely a natural transformation. We need to new datatype (instead of simply using a forall) due to lack of support in GHC for impredicative types.





askUnliftIO :: MonadUnliftIO m => m (UnliftIO m) Source #

Capture the current monadic context, providing the ability to run monadic actions in IO.

See UnliftIO for an explanation of why we need a helper datatype here.

Prior to version of this library, this was a method in the MonadUnliftIO type class. It was moved out due to https://github.com/fpco/unliftio/issues/55.


askRunInIO :: MonadUnliftIO m => m (m a -> IO a) Source #

Same as askUnliftIO, but returns a monomorphic function instead of a polymorphic newtype wrapper. If you only need to apply the transformation on one concrete type, this function can be more convenient.


withUnliftIO :: MonadUnliftIO m => (UnliftIO m -> IO a) -> m a Source #

Convenience function for capturing the monadic context and running an IO action. The UnliftIO newtype wrapper is rarely needed, so prefer withRunInIO to this function.


toIO :: MonadUnliftIO m => m a -> m (IO a) Source #

Convert an action in m to an action in IO.


wrappedWithRunInIO Source #


:: MonadUnliftIO n 
=> (n b -> m b)

The wrapper, for instance IdentityT.

-> (forall a. m a -> n a)

The inverse, for instance runIdentityT.

-> ((forall a. m a -> IO a) -> IO b)

The actual function to invoke withRunInIO with.

-> m b 

A helper function for implementing MonadUnliftIO instances. Useful for the common case where you want to simply delegate to the underlying transformer.


newtype AppT m a = AppT { unAppT :: ReaderT Int (ResourceT m) a }
  deriving (Functor, Applicative, Monad, MonadIO)
  -- Unfortunately, deriving MonadUnliftIO does not work.

instance MonadUnliftIO m => MonadUnliftIO (AppT m) where
  withRunInIO = wrappedWithRunInIO AppT unAppT


class Monad m => MonadIO (m :: Type -> Type) where #

Monads in which IO computations may be embedded. Any monad built by applying a sequence of monad transformers to the IO monad will be an instance of this class.

Instances should satisfy the following laws, which state that liftIO is a transformer of monads:


liftIO :: IO a -> m a #

Lift a computation from the IO monad.

MonadIO IO

Since: base-

Instance details

Defined in Control.Monad.IO.Class


liftIO :: IO a -> IO a #

MonadIO m => MonadIO (IdentityT m) 
Instance details

Defined in Control.Monad.Trans.Identity


liftIO :: IO a -> IdentityT m a #

MonadIO m => MonadIO (ReaderT r m) 
Instance details

Defined in Control.Monad.Trans.Reader


liftIO :: IO a -> ReaderT r m a #