{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-deprecations #-}
module Control.Monad.Trans.Introspect where
import Control.Applicative
import Control.Monad hiding (fail)
import Control.Monad.Cont.Class
import Control.Monad.Error.Class
import Control.Monad.Fail
import Control.Monad.Fix
import Control.Monad.IO.Class
import Control.Monad.Reader.Class
import Control.Monad.Signatures
import Control.Monad.State.Class
import Control.Monad.Trans.Class
import Control.Monad.Writer.Class
import Control.Monad.Zip
import Data.Coerce
import Prelude hiding (fail)
import Control.Monad.Introspect.Class
import Data.Type.Role.Representational
newtype IntrospectT
(t :: (* -> *) -> * -> *)
(r :: (* -> *) -> *)
(m :: * -> *)
(a :: *)
= IntrospectT { runIntrospectT :: r (t (IntrospectT t r m)) -> m a }
runIntrospect :: (Representational r, Coercible (t (IntrospectT t r m)) n)
=> r n -> IntrospectT t r m a -> m a
runIntrospect e (IntrospectT h) = h $ liftTransEnv e
instance Functor m => Functor (IntrospectT t r m) where
fmap f (IntrospectT h) = IntrospectT $ fmap f . h
instance Applicative m => Applicative (IntrospectT t r m) where
pure x = IntrospectT $ const $ pure x
IntrospectT f <*> IntrospectT x = IntrospectT $ liftA2 (<*>) f x
instance Alternative m => Alternative (IntrospectT t r m) where
empty = IntrospectT $ const empty
IntrospectT f <|> IntrospectT g = IntrospectT $ liftA2 (<|>) f g
instance Monad m => Monad (IntrospectT t r m) where
IntrospectT k >>= f = IntrospectT $ \e -> k e >>= \x -> runIntrospectT (f x) e
instance MonadPlus m => MonadPlus (IntrospectT t r m) where
mzero = IntrospectT $ const mzero
mplus (IntrospectT f) (IntrospectT g) = IntrospectT $ liftA2 mplus f g
instance MonadTrans (IntrospectT t r) where
lift k = IntrospectT $ const k
instance (Monad m, MonadTrans t)
=> MonadIntrospectTrans t r (IntrospectT t r m) where
introspectTrans = IntrospectT return
substituteTrans f (IntrospectT h) = IntrospectT $ h . f
mapIntrospectT :: (m a -> m b) -> IntrospectT t r m a -> IntrospectT t r m b
mapIntrospectT f (IntrospectT h) = IntrospectT $ f . h
liftCallCC :: CallCC m a b -> CallCC (IntrospectT t r m) a b
liftCallCC cCC f = IntrospectT $ \r ->
cCC $ \c -> runIntrospectT (f (IntrospectT . const . c)) r
liftCatch :: Catch e m a -> Catch e (IntrospectT t r m) a
liftCatch f m h = IntrospectT $ \r ->
f (runIntrospectT m r) $ \e -> runIntrospectT (h e) r
instance MonadError e m => MonadError e (IntrospectT t r m) where
throwError = lift . throwError
catchError = liftCatch catchError
instance MonadReader e m => MonadReader e (IntrospectT t r m) where
ask = lift ask
local = mapIntrospectT . local
reader = lift . reader
instance MonadState s m => MonadState s (IntrospectT t r m) where
get = lift get
put = lift . put
state = lift . state
instance MonadWriter w m => MonadWriter w (IntrospectT t r m) where
writer = lift . writer
tell = lift . tell
listen = mapIntrospectT listen
pass = mapIntrospectT pass
instance MonadCont m => MonadCont (IntrospectT t r m) where
callCC = liftCallCC callCC
instance MonadFix m => MonadFix (IntrospectT t r m) where
mfix f = IntrospectT $ \r -> mfix $ \a -> runIntrospectT (f a) r
instance MonadFail m => MonadFail (IntrospectT t r m) where
fail = lift . fail
instance MonadZip m => MonadZip (IntrospectT t r m) where
mzip (IntrospectT f) (IntrospectT g) = IntrospectT $ \r -> mzip (f r) (g r)
mzipWith h (IntrospectT f) (IntrospectT g) = IntrospectT $ \r ->
mzipWith h (f r) (g r)
instance MonadIO m => MonadIO (IntrospectT t r m) where
liftIO = lift . liftIO