-- 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
--   https://www.stackage.org/package/unliftio-core
@package unliftio-core
@version 0.2.1.0

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

-- | 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:
--   
--   
--   
- 
run . return = return

--   
- 
run (m >>= f) = run m >>= run . f

--   
--   
--   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.
class MonadIO m => MonadUnliftIO (m :: Type -> Type)

-- | 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.
withRunInIO :: MonadUnliftIO m => ((forall a. () => m a -> IO a) -> IO b) -> m b

-- | 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.
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 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.
askUnliftIO :: MonadUnliftIO m => m (UnliftIO m)

-- | 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.
askRunInIO :: MonadUnliftIO m => m (m a -> IO 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.
withUnliftIO :: MonadUnliftIO m => (UnliftIO m -> IO a) -> m a

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

-- | A helper function for implementing MonadUnliftIO instances.
--   Useful for the common case where you want to simply delegate to the
--   underlying transformer.
--   
--   Note: You can derive MonadUnliftIO for newtypes without this
--   helper function in unliftio-core 0.2.0.0 and later.
--   
--   
Example
--   
--   
--   newtype AppT m a = AppT { unAppT :: ReaderT Int (ResourceT m) a }
--     deriving (Functor, Applicative, Monad, MonadIO)
--   
--   -- Same as `deriving newtype (MonadUnliftIO)`
--   instance MonadUnliftIO m => MonadUnliftIO (AppT m) where
--     withRunInIO = wrappedWithRunInIO AppT unAppT
--   
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 IO a -> IO b functions into
--   any MonadUnliftIO.
--   
--   
Example
--   
--   
--   liftedTry :: (Exception e, MonadUnliftIO m) => m a -> m (Either e a)
--   liftedTry m = liftIOOp Control.Exception.try m
--   
liftIOOp :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b

-- | 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 . return = return

--   
- 
liftIO (m >>= f) = liftIO m >>=
--   (liftIO . f)

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

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