Control.Monad.IO.Unlift

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

Safe Haskell | Safe-Inferred
Language | Haskell2010

Control.Monad.IO.Unlift

Description

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

Synopsis

- class MonadIO m => MonadUnliftIO m where
  - withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b
- newtype UnliftIO m = UnliftIO {
  - unliftIO :: forall a. m a -> IO a
  }
- askUnliftIO :: MonadUnliftIO m => m (UnliftIO m)
- askRunInIO :: MonadUnliftIO m => m (m a -> IO a)
- withUnliftIO :: MonadUnliftIO m => (UnliftIO m -> IO a) -> m a
- toIO :: MonadUnliftIO m => m a -> m (IO a)
- wrappedWithRunInIO :: MonadUnliftIO n => (n b -> m b) -> (forall a. m a -> n a) -> ((forall a. m a -> IO a) -> IO b) -> m b
- class Monad m => MonadIO (m :: Type -> Type) where
  - liftIO :: IO a -> m a

# Documentation

class MonadIO m => MonadUnliftIO m where #

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`.

Since: 0.1.0.0

Methods

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

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`.

Since: 0.1.0.0

#### Instances

Instances details

MonadUnliftIO IO # |
Instance details Defined in Control.Monad.IO.Unlift Methods withRunInIO :: ((forall a. IO a -> IO a) -> IO b) -> IO b #
MonadUnliftIO m => MonadUnliftIO (IdentityT m) # |
Instance details Defined in Control.Monad.IO.Unlift Methods withRunInIO :: ((forall a. IdentityT m a -> IO a) -> IO b) -> IdentityT m b #
MonadUnliftIO m => MonadUnliftIO (ReaderT r m) # |
Instance details Defined in Control.Monad.IO.Unlift Methods withRunInIO :: ((forall a. ReaderT r m a -> IO a) -> IO b) -> ReaderT r m b #

newtype UnliftIO m #

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.

Since: 0.1.0.0

Constructors

UnliftIO |
Fields unliftIO :: forall a. m a -> IO a

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

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 0.2.0.0 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.

Since: 0.1.0.0

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

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.

Since: 0.1.0.0

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

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.

Since: 0.1.0.0

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

Convert an action in `m` to an action in `IO`.

Since: 0.1.0.0

wrappedWithRunInIO #

Arguments

:: 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.

#### Example

Expand

    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

Since: 0.1.2.0

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

Methods

liftIO :: IO a -> m a #

#### Instances

Instances details

MonadIO IO |
Instance details Defined in Control.Monad.IO.Class Methods liftIO :: IO a -> IO a #
MonadIO m => MonadIO (IdentityT m) |
Instance details Defined in Control.Monad.Trans.Identity Methods liftIO :: IO a -> IdentityT m a #
MonadIO m => MonadIO (ReaderT r m) |
Instance details Defined in Control.Monad.Trans.Reader Methods liftIO :: IO a -> ReaderT r m a #