{-# LANGUAGE CPP, RankNTypes #-} module Control.Monad.Trans.AnyCont where import LLVM.Prelude import Control.Monad.Catch import Control.Monad.Cont as Cont import Control.Monad.Fail as Fail newtype AnyContT m a = AnyContT { unAnyContT :: forall r . ContT r m a } instance Functor (AnyContT m) where fmap f p = AnyContT $ fmap f (unAnyContT p) {-# INLINE fmap #-} instance Applicative (AnyContT m) where pure a = AnyContT $ pure a {-# INLINE pure #-} f <*> v = AnyContT $ unAnyContT f <*> unAnyContT v {-# INLINE (<*>) #-} instance Monad m => Monad (AnyContT m) where AnyContT f >>= k = AnyContT $ f >>= \x -> unAnyContT (k x) {-# INLINE (>>=) #-} return a = AnyContT $ return a {-# INLINE return #-} #if !(MIN_VERSION_base(4,13,0)) fail s = AnyContT (ContT (\_ -> Cont.fail s)) {-# INLINE fail #-} #endif instance MonadFail m => MonadFail (AnyContT m) where fail s = AnyContT (ContT (\_ -> Fail.fail s)) {-# INLINE fail #-} instance MonadIO m => MonadIO (AnyContT m) where liftIO = lift . liftIO {-# INLINE liftIO #-} instance MonadTrans AnyContT where lift ma = AnyContT (lift ma) {-# INLINE lift #-} instance MonadThrow m => MonadThrow (AnyContT m) where throwM = lift . throwM {-# INLINE throwM #-} runAnyContT :: AnyContT m a -> forall r . (a -> m r) -> m r runAnyContT k = runContT (unAnyContT k) {-# INLINE runAnyContT #-} runAnyContT' :: (a -> m r) -> AnyContT m a -> m r runAnyContT' f k = runContT (unAnyContT k) f {-# INLINE runAnyContT' #-} anyContT :: (forall r . (a -> m r) -> m r) -> AnyContT m a anyContT f = AnyContT (ContT f) {-# INLINE anyContT #-} withAnyContT :: (forall r . (b -> m r) -> (a -> m r)) -> AnyContT m a -> AnyContT m b withAnyContT f m = anyContT $ runAnyContT m . f {-# INLINE withAnyContT #-} mapAnyContT :: (forall r . m r -> m r) -> AnyContT m a -> AnyContT m a mapAnyContT f m = anyContT $ f . runAnyContT m {-# INLINE mapAnyContT #-}