{-# LANGUAGE RankNTypes #-}
module Control.Monad.IO.Unlift
( MonadUnliftIO (..)
, UnliftIO (..)
, askUnliftIO
, askRunInIO
, withUnliftIO
, toIO
, wrappedWithRunInIO
, liftIOOp
, MonadIO (..)
) where
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader (ReaderT (..))
import Control.Monad.Trans.Identity (IdentityT (..))
newtype UnliftIO m = UnliftIO { forall (m :: * -> *). UnliftIO m -> forall a. m a -> IO a
unliftIO :: forall a. m a -> IO a }
class MonadIO m => MonadUnliftIO m where
withRunInIO :: ((forall a. m a -> IO a) -> IO b) -> m b
instance MonadUnliftIO IO where
{-# INLINE withRunInIO #-}
withRunInIO :: forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
withRunInIO (forall a. IO a -> IO a) -> IO b
inner = (forall a. IO a -> IO a) -> IO b
inner forall a. a -> a
id
instance MonadUnliftIO m => MonadUnliftIO (ReaderT r m) where
{-# INLINE withRunInIO #-}
withRunInIO :: forall b.
((forall a. ReaderT r m a -> IO a) -> IO b) -> ReaderT r m b
withRunInIO (forall a. ReaderT r m a -> IO a) -> IO b
inner =
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT forall a b. (a -> b) -> a -> b
$ \r
r ->
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run ->
(forall a. ReaderT r m a -> IO a) -> IO b
inner (forall a. m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT r
r)
instance MonadUnliftIO m => MonadUnliftIO (IdentityT m) where
{-# INLINE withRunInIO #-}
withRunInIO :: forall b.
((forall a. IdentityT m a -> IO a) -> IO b) -> IdentityT m b
withRunInIO (forall a. IdentityT m a -> IO a) -> IO b
inner =
forall {k} (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT forall a b. (a -> b) -> a -> b
$
forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run ->
(forall a. IdentityT m a -> IO a) -> IO b
inner (forall a. m a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall {k} (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT)
askUnliftIO :: MonadUnliftIO m => m (UnliftIO m)
askUnliftIO :: forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (\forall a. m a -> IO a
run -> forall (m :: * -> *) a. Monad m => a -> m a
return (forall (m :: * -> *). (forall a. m a -> IO a) -> UnliftIO m
UnliftIO forall a. m a -> IO a
run))
{-# INLINE askUnliftIO #-}
{-# INLINE askRunInIO #-}
askRunInIO :: MonadUnliftIO m => m (m a -> IO a)
askRunInIO :: forall (m :: * -> *) a. MonadUnliftIO m => m (m a -> IO a)
askRunInIO = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO (\forall a. m a -> IO a
run -> (forall (m :: * -> *) a. Monad m => a -> m a
return (\m a
ma -> forall a. m a -> IO a
run m a
ma)))
{-# INLINE withUnliftIO #-}
withUnliftIO :: MonadUnliftIO m => (UnliftIO m -> IO a) -> m a
withUnliftIO :: forall (m :: * -> *) a.
MonadUnliftIO m =>
(UnliftIO m -> IO a) -> m a
withUnliftIO UnliftIO m -> IO a
inner = forall (m :: * -> *). MonadUnliftIO m => m (UnliftIO m)
askUnliftIO forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall b c a. (b -> c) -> (a -> b) -> a -> c
. UnliftIO m -> IO a
inner
{-# INLINE toIO #-}
toIO :: MonadUnliftIO m => m a -> m (IO a)
toIO :: forall (m :: * -> *) a. MonadUnliftIO m => m a -> m (IO a)
toIO m a
m = forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. m a -> IO a
run -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. m a -> IO a
run m a
m
{-# INLINE wrappedWithRunInIO #-}
wrappedWithRunInIO :: MonadUnliftIO n
=> (n b -> m b)
-> (forall a. m a -> n a)
-> ((forall a. m a -> IO a) -> IO b)
-> m b
wrappedWithRunInIO :: forall (n :: * -> *) b (m :: * -> *).
MonadUnliftIO n =>
(n b -> m b)
-> (forall a. m a -> n a)
-> ((forall a. m a -> IO a) -> IO b)
-> m b
wrappedWithRunInIO n b -> m b
wrap forall a. m a -> n a
unwrap (forall a. m a -> IO a) -> IO b
inner = n b -> m b
wrap forall a b. (a -> b) -> a -> b
$ forall (m :: * -> *) b.
MonadUnliftIO m =>
((forall a. m a -> IO a) -> IO b) -> m b
withRunInIO forall a b. (a -> b) -> a -> b
$ \forall a. n a -> IO a
run ->
(forall a. m a -> IO a) -> IO b
inner forall a b. (a -> b) -> a -> b
$ forall a. n a -> IO a
run forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. m a -> n a
unwrap
liftIOOp :: MonadUnliftIO m => (IO a -> IO b) -> m a -> m b
liftIOOp :: forall (m :: * -> *) a b.
MonadUnliftIO m =>
(IO a -> IO b) -> m a -> m b
liftIOOp IO a -> IO b
f m a
x = do
m a -> IO a
runInIO <- forall (m :: * -> *) a. MonadUnliftIO m => m (m a -> IO a)
askRunInIO
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ IO a -> IO b
f forall a b. (a -> b) -> a -> b
$ m a -> IO a
runInIO m a
x