-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Please see the documentation and README at
--   <a>https://www.stackage.org/package/unliftio-core</a>
@package unliftio-core
@version 0.2.1.0


-- | Please see the README.md file for information on using this package at
--   <a>https://www.stackage.org/package/unliftio-core</a>.
module Control.Monad.IO.Unlift

-- | Monads which allow their actions to be run in <a>IO</a>.
--   
--   While <a>MonadIO</a> allows an <a>IO</a> 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
--   <a>MonadUnliftIO</a> to <a>ReaderT</a> and <a>IdentityT</a>
--   transformers on top of <a>IO</a>.
--   
--   Laws. For any function <tt>run</tt> provided by <a>withRunInIO</a>, it
--   must meet the monad transformer laws as reformulated for
--   <tt>MonadUnliftIO</tt>:
--   
--   <ul>
--   <li><pre>run . return = return</pre></li>
--   <li><pre>run (m &gt;&gt;= f) = run m &gt;&gt;= run . f</pre></li>
--   </ul>
--   
--   Instances of <tt>MonadUnliftIO</tt> must also satisfy the following
--   laws:
--   
--   <ul>
--   <li><i>Identity law</i> <tt>withRunInIO (\run -&gt; run m) =
--   m</tt></li>
--   <li><i>Inverse law</i> <tt>withRunInIO (\_ -&gt; m) = liftIO
--   m</tt></li>
--   </ul>
--   
--   As an example of an invalid instance, a naive implementation of
--   <tt>MonadUnliftIO (StateT s m)</tt> might be
--   
--   <pre>
--   withRunInIO inner =
--     StateT $ \s -&gt;
--       withRunInIO $ \run -&gt;
--         inner (run . flip evalStateT s)
--   </pre>
--   
--   This breaks the identity law because the inner <tt>run m</tt> would
--   throw away any state changes in <tt>m</tt>.
class MonadIO m => MonadUnliftIO (m :: Type -> Type)

-- | Convenience function for capturing the monadic context and running an
--   <a>IO</a> action with a runner function. The runner function is used
--   to run a monadic action <tt>m</tt> in <tt>IO</tt>.
withRunInIO :: MonadUnliftIO m => ((forall a. () => m a -> IO a) -> IO b) -> m b

-- | The ability to run any monadic action <tt>m a</tt> as <tt>IO a</tt>.
--   
--   This is more precisely a natural transformation. We need to new
--   datatype (instead of simply using a <tt>forall</tt>) due to lack of
--   support in GHC for impredicative types.
newtype UnliftIO (m :: Type -> Type)
UnliftIO :: (forall a. () => m a -> IO a) -> UnliftIO (m :: Type -> Type)
[unliftIO] :: UnliftIO (m :: Type -> Type) -> forall a. () => m a -> IO a

-- | Capture the current monadic context, providing the ability to run
--   monadic actions in <a>IO</a>.
--   
--   See <a>UnliftIO</a> 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
--   <a>MonadUnliftIO</a> type class. It was moved out due to
--   <a>https://github.com/fpco/unliftio/issues/55</a>.
askUnliftIO :: MonadUnliftIO m => m (UnliftIO m)

-- | Same as <a>askUnliftIO</a>, 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.
askRunInIO :: MonadUnliftIO m => m (m a -> IO a)

-- | Convenience function for capturing the monadic context and running an
--   <a>IO</a> action. The <a>UnliftIO</a> newtype wrapper is rarely
--   needed, so prefer <a>withRunInIO</a> to this function.
withUnliftIO :: MonadUnliftIO m => (UnliftIO m -> IO a) -> m a

-- | Convert an action in <tt>m</tt> to an action in <tt>IO</tt>.
toIO :: MonadUnliftIO m => m a -> m (IO a)

-- | A helper function for implementing <tt>MonadUnliftIO</tt> instances.
--   Useful for the common case where you want to simply delegate to the
--   underlying transformer.
--   
--   Note: You can derive <a>MonadUnliftIO</a> for newtypes without this
--   helper function in <tt>unliftio-core</tt> 0.2.0.0 and later.
--   
--   <h4><b>Example</b></h4>
--   
--   <pre>
--   newtype AppT m a = AppT { unAppT :: ReaderT Int (ResourceT m) a }
--     deriving (Functor, Applicative, Monad, MonadIO)
--   
--   -- Same as `deriving newtype (MonadUnliftIO)`
--   instance MonadUnliftIO m =&gt; MonadUnliftIO (AppT m) where
--     withRunInIO = wrappedWithRunInIO AppT unAppT
--   </pre>
wrappedWithRunInIO :: MonadUnliftIO n => (n b -> m b) -> (forall a. () => m a -> n a) -> ((forall a. () => m a -> IO a) -> IO b) -> m b

-- | A helper function for lifting <tt>IO a -&gt; IO b</tt> functions into
--   any <tt>MonadUnliftIO</tt>.
--   
--   <h3><b>Example</b></h3>
--   
--   <pre>
--   liftedTry :: (Exception e, MonadUnliftIO m) =&gt; m a -&gt; m (Either e a)
--   liftedTry m = liftIOOp Control.Exception.try m
--   </pre>
liftIOOp :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b
class Monad m => MonadIO (m :: Type -> Type)
liftIO :: MonadIO m => IO a -> m a
instance Control.Monad.IO.Unlift.MonadUnliftIO GHC.Types.IO
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Control.Monad.Trans.Identity.IdentityT m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Control.Monad.Trans.Reader.ReaderT r m)
