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


-- | The MonadUnliftIO typeclass for unlifting monads to IO
--   
--   Please see the documentation and README at
--   <a>https://www.stackage.org/package/unliftio-core</a>
@package unliftio-core
@version 0.2.0.1


-- | 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 value <tt>u</tt> returned by <a>askUnliftIO</a>, it must
--   meet the monad transformer laws as reformulated for
--   <tt>MonadUnliftIO</tt>:
--   
--   <ul>
--   <li><pre>unliftIO u . return = return</pre></li>
--   <li><pre>unliftIO u (m &gt;&gt;= f) = unliftIO u m &gt;&gt;= unliftIO
--   u . f</pre></li>
--   </ul>
--   
--   Instances of <tt>MonadUnliftIO</tt> must also satisfy the idempotency
--   law:
--   
--   <ul>
--   <li><pre>askUnliftIO &gt;&gt;= \u -&gt; (liftIO . unliftIO u) m =
--   m</pre></li>
--   </ul>
--   
--   This law showcases two properties. First, <a>askUnliftIO</a> doesn't
--   change the monadic context, and second, <tt>liftIO . unliftIO u</tt>
--   is equivalent to <tt>id</tt> IF called in the same monadic context as
--   <a>askUnliftIO</a>.
class MonadIO m => MonadUnliftIO m

-- | 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
UnliftIO :: (forall a. m a -> IO a) -> UnliftIO m
[unliftIO] :: UnliftIO m -> 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.
--   
--   <h4><b>Example</b></h4>
--   
--   <pre>
--   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 =&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

-- | Monads in which <a>IO</a> computations may be embedded. Any monad
--   built by applying a sequence of monad transformers to the <a>IO</a>
--   monad will be an instance of this class.
--   
--   Instances should satisfy the following laws, which state that
--   <a>liftIO</a> is a transformer of monads:
--   
--   <ul>
--   <li><pre><a>liftIO</a> . <a>return</a> = <a>return</a></pre></li>
--   <li><pre><a>liftIO</a> (m &gt;&gt;= f) = <a>liftIO</a> m &gt;&gt;=
--   (<a>liftIO</a> . f)</pre></li>
--   </ul>
class Monad m => MonadIO (m :: Type -> Type)

-- | Lift a computation from the <a>IO</a> monad. This allows us to run IO
--   computations in any monadic stack, so long as it supports these kinds
--   of operations (i.e. <a>IO</a> is the base monad for the stack).
--   
--   <h3><b>Example</b></h3>
--   
--   <pre>
--   import Control.Monad.Trans.State -- from the "transformers" library
--   
--   printState :: Show s =&gt; StateT s IO ()
--   printState = do
--     state &lt;- get
--     liftIO $ print state
--   </pre>
--   
--   Had we omitted <tt><a>liftIO</a></tt>, we would have ended up with
--   this error:
--   
--   <pre>
--   • Couldn't match type ‘IO’ with ‘StateT s IO’
--    Expected type: StateT s IO ()
--      Actual type: IO ()
--   </pre>
--   
--   The important part here is the mismatch between <tt>StateT s IO
--   ()</tt> and <tt><a>IO</a> ()</tt>.
--   
--   Luckily, we know of a function that takes an <tt><a>IO</a> a</tt> and
--   returns an <tt>(m a)</tt>: <tt><a>liftIO</a></tt>, enabling us to run
--   the program and see the expected results:
--   
--   <pre>
--   &gt; evalStateT printState "hello"
--   "hello"
--   
--   &gt; evalStateT printState 3
--   3
--   </pre>
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.Reader.ReaderT r m)
instance Control.Monad.IO.Unlift.MonadUnliftIO m => Control.Monad.IO.Unlift.MonadUnliftIO (Control.Monad.Trans.Identity.IdentityT m)
