{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE UndecidableInstances #-}
module Unlift
( MonadUnlift (..)
, defaultWithRunInBase
, askRunInBase
, Unlift (..)
, askUnlift
) where
import Control.Monad.Base (MonadBase)
import Control.Monad.ST (ST)
import Control.Monad.STM (STM)
import Control.Monad.Trans.Identity (IdentityT (..))
import Control.Monad.Trans.Reader (ReaderT (..))
class (MonadBase b m) => MonadUnlift b m
where
withRunInBase :: ((forall a . m a -> b a) -> b x) -> m x
instance MonadUnlift IO IO
where
withRunInBase :: ((forall a . IO a -> IO a) -> IO x) -> IO x
withRunInBase :: ((forall a. IO a -> IO a) -> IO x) -> IO x
withRunInBase = \(forall a. IO a -> IO a) -> IO x
run -> (forall a. IO a -> IO a) -> IO x
run forall a. a -> a
forall a. IO a -> IO a
id
instance MonadUnlift STM STM
where
withRunInBase :: ((forall a . STM a -> STM a) -> STM x) -> STM x
withRunInBase :: ((forall a. STM a -> STM a) -> STM x) -> STM x
withRunInBase = \(forall a. STM a -> STM a) -> STM x
run -> (forall a. STM a -> STM a) -> STM x
run forall a. a -> a
forall a. STM a -> STM a
id
instance MonadUnlift (ST s) (ST s)
where
withRunInBase :: ((forall a . ST s a -> ST s a) -> ST s x) -> ST s x
withRunInBase :: ((forall a. ST s a -> ST s a) -> ST s x) -> ST s x
withRunInBase = \(forall a. ST s a -> ST s a) -> ST s x
run -> (forall a. ST s a -> ST s a) -> ST s x
run forall a. a -> a
forall a. ST s a -> ST s a
id
instance (MonadUnlift b m) => MonadUnlift b (IdentityT m)
where
withRunInBase :: ((forall a . IdentityT m a -> b a) -> b x) -> IdentityT m x
withRunInBase :: ((forall a. IdentityT m a -> b a) -> b x) -> IdentityT m x
withRunInBase = (m x -> IdentityT m x)
-> (forall a. IdentityT m a -> m a)
-> ((forall a. IdentityT m a -> b a) -> b x)
-> IdentityT m x
forall (b :: * -> *) (n :: * -> *) x (m :: * -> *).
MonadUnlift b n =>
(n x -> m x)
-> (forall a. m a -> n a) -> ((forall a. m a -> b a) -> b x) -> m x
defaultWithRunInBase m x -> IdentityT m x
forall k (f :: k -> *) (a :: k). f a -> IdentityT f a
IdentityT forall a. IdentityT m a -> m a
forall k (f :: k -> *) (a :: k). IdentityT f a -> f a
runIdentityT
instance (MonadUnlift b m) => MonadUnlift b (ReaderT r m)
where
withRunInBase :: ((forall a . ReaderT r m a -> b a) -> b x) -> ReaderT r m x
withRunInBase :: ((forall a. ReaderT r m a -> b a) -> b x) -> ReaderT r m x
withRunInBase (forall a. ReaderT r m a -> b a) -> b x
runWithReader = (r -> m x) -> ReaderT r m x
forall r (m :: * -> *) a. (r -> m a) -> ReaderT r m a
ReaderT ((r -> m x) -> ReaderT r m x) -> (r -> m x) -> ReaderT r m x
forall a b. (a -> b) -> a -> b
$ \r
env ->
((forall a. m a -> b a) -> b x) -> m x
forall (b :: * -> *) (m :: * -> *) x.
MonadUnlift b m =>
((forall a. m a -> b a) -> b x) -> m x
withRunInBase (\forall a. m a -> b a
ma2ba -> (forall a. ReaderT r m a -> b a) -> b x
runWithReader (m a -> b a
forall a. m a -> b a
ma2ba (m a -> b a) -> (ReaderT r m a -> m a) -> ReaderT r m a -> b a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ReaderT r m a -> r -> m a) -> r -> ReaderT r m a -> m a
forall a b c. (a -> b -> c) -> b -> a -> c
flip ReaderT r m a -> r -> m a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT r
env))
defaultWithRunInBase
:: (MonadUnlift b n)
=> (n x -> m x)
-> (forall a . m a -> n a)
-> ((forall a . m a -> b a) -> b x)
-> m x
defaultWithRunInBase :: (n x -> m x)
-> (forall a. m a -> n a) -> ((forall a. m a -> b a) -> b x) -> m x
defaultWithRunInBase n x -> m x
wrap forall a. m a -> n a
unwrap (forall a. m a -> b a) -> b x
run =
n x -> m x
wrap (n x -> m x) -> n x -> m x
forall a b. (a -> b) -> a -> b
$ ((forall a. n a -> b a) -> b x) -> n x
forall (b :: * -> *) (m :: * -> *) x.
MonadUnlift b m =>
((forall a. m a -> b a) -> b x) -> m x
withRunInBase (\forall a. n a -> b a
ma2ba -> (forall a. m a -> b a) -> b x
run (n a -> b a
forall a. n a -> b a
ma2ba (n a -> b a) -> (m a -> n a) -> m a -> b a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. m a -> n a
forall a. m a -> n a
unwrap))
askRunInBase :: (MonadUnlift b m) => m (m a -> b a)
askRunInBase :: m (m a -> b a)
askRunInBase = ((forall a. m a -> b a) -> b (m a -> b a)) -> m (m a -> b a)
forall (b :: * -> *) (m :: * -> *) x.
MonadUnlift b m =>
((forall a. m a -> b a) -> b x) -> m x
withRunInBase (((forall a. m a -> b a) -> b (m a -> b a)) -> m (m a -> b a))
-> ((forall a. m a -> b a) -> b (m a -> b a)) -> m (m a -> b a)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> b a
run -> (m a -> b a) -> b (m a -> b a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure m a -> b a
forall a. m a -> b a
run
newtype Unlift b m = Unlift
{ Unlift b m -> forall x. m x -> b x
runUnlift :: forall x . m x -> b x
}
askUnlift :: (MonadUnlift b m) => m (Unlift b m)
askUnlift :: m (Unlift b m)
askUnlift = ((forall a. m a -> b a) -> b (Unlift b m)) -> m (Unlift b m)
forall (b :: * -> *) (m :: * -> *) x.
MonadUnlift b m =>
((forall a. m a -> b a) -> b x) -> m x
withRunInBase (((forall a. m a -> b a) -> b (Unlift b m)) -> m (Unlift b m))
-> ((forall a. m a -> b a) -> b (Unlift b m)) -> m (Unlift b m)
forall a b. (a -> b) -> a -> b
$ \forall a. m a -> b a
runInBase -> Unlift b m -> b (Unlift b m)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((forall a. m a -> b a) -> Unlift b m
forall (b :: * -> *) (m :: * -> *).
(forall x. m x -> b x) -> Unlift b m
Unlift forall a. m a -> b a
runInBase)