module Control.Monad.Trans.Identity.Tagged
(
TaggedT (..)
, mapTaggedT
, liftCallCC
, liftCatch )
where
import Control.Applicative
import Control.Monad (MonadPlus (..))
import Control.Monad.Cont.Class
import Control.Monad.Error.Class
import Control.Monad.IO.Class (MonadIO (..))
import Control.Monad.RWS.Class
import Control.Monad.Signatures
import Control.Monad.Trans.Class (MonadTrans (..))
import Control.Monad.Zip (MonadZip (..))
#if !MIN_VERSION_base(4,8,0)
import Data.Foldable (Foldable (..))
import Data.Traversable (Traversable (..))
#endif
#if MIN_VERSION_base(4,9,0)
import Data.Functor.Classes
import qualified Control.Monad.Fail as Fail
#endif
import Control.Monad.Fix (MonadFix (..))
newtype TaggedT tag f a = TaggedT { runTaggedT :: f a }
#if MIN_VERSION_base(4,9,0)
instance Eq1 f => Eq1 (TaggedT tag f) where
liftEq eq (TaggedT x) (TaggedT y) = liftEq eq x y
instance Ord1 f => Ord1 (TaggedT tag f) where
liftCompare comp (TaggedT x) (TaggedT y) = liftCompare comp x y
instance Read1 f => Read1 (TaggedT tag f) where
liftReadsPrec rp rl = readsData $
readsUnaryWith (liftReadsPrec rp rl) "TaggedT" TaggedT
instance Show1 f => Show1 (TaggedT tag f) where
liftShowsPrec sp sl d (TaggedT m) =
showsUnaryWith (liftShowsPrec sp sl) "TaggedT" d m
instance (Eq1 f, Eq a) => Eq (TaggedT tag f a) where
(==) = eq1
instance (Ord1 f, Ord a) => Ord (TaggedT tag f a) where
compare = compare1
instance (Read1 f, Read a) => Read (TaggedT tag f a) where
readsPrec = readsPrec1
instance (Show1 f, Show a) => Show (TaggedT tag f a) where
showsPrec = showsPrec1
#endif
instance Functor m => Functor (TaggedT tag m) where
fmap f = mapTaggedT (fmap f)
instance Foldable f => Foldable (TaggedT tag f) where
foldMap f (TaggedT a) = foldMap f a
instance Traversable f => Traversable (TaggedT tag f) where
traverse f (TaggedT a) = TaggedT <$> traverse f a
instance Applicative m => Applicative (TaggedT tag m) where
pure x = TaggedT (pure x)
(<*>) = lift2TaggedT (<*>)
instance Alternative m => Alternative (TaggedT tag m) where
empty = TaggedT empty
(<|>) = lift2TaggedT (<|>)
instance Monad m => Monad (TaggedT tag m) where
#if !(MIN_VERSION_base(4,8,0))
return = TaggedT . return
#endif
m >>= k = TaggedT $ runTaggedT . k =<< runTaggedT m
fail msg = TaggedT $ fail msg
#if MIN_VERSION_base(4,9,0)
instance Fail.MonadFail m => Fail.MonadFail (TaggedT tag m) where
fail msg = TaggedT $ Fail.fail msg
#endif
instance MonadPlus m => MonadPlus (TaggedT tag m) where
mzero = TaggedT mzero
mplus = lift2TaggedT mplus
instance MonadFix m => MonadFix (TaggedT tag m) where
mfix f = TaggedT (mfix (runTaggedT . f))
instance MonadIO m => MonadIO (TaggedT tag m) where
liftIO = TaggedT . liftIO
#if MIN_VERSION_base(4,4,0)
instance MonadZip m => MonadZip (TaggedT tag m) where
mzipWith f = lift2TaggedT (mzipWith f)
#endif
instance MonadTrans (TaggedT tag) where
lift = TaggedT
mapTaggedT :: (m a -> n b) -> TaggedT tag m a -> TaggedT tag n b
mapTaggedT f = TaggedT . f . runTaggedT
lift2TaggedT :: (m a -> n b -> p c) -> TaggedT tag m a -> TaggedT tag n b -> TaggedT tag p c
lift2TaggedT f a b = TaggedT (f (runTaggedT a) (runTaggedT b))
liftCallCC :: CallCC m a b -> CallCC (TaggedT tag m) a b
liftCallCC callCC' f =
TaggedT $ callCC' $ \ c -> runTaggedT (f (TaggedT . c))
liftCatch :: Catch e m a -> Catch e (TaggedT tag m) a
liftCatch f m h = TaggedT $ f (runTaggedT m) (runTaggedT . h)
instance MonadCont m => MonadCont (TaggedT tag m) where
callCC = liftCallCC callCC
instance MonadError e m => MonadError e (TaggedT tag m) where
throwError = lift . throwError
catchError = liftCatch catchError
instance MonadRWS r w s m => MonadRWS r w s (TaggedT tag m)
instance MonadReader r m => MonadReader r (TaggedT tag m) where
ask = lift ask
local = mapTaggedT . local
reader = lift . reader
instance MonadState s m => MonadState s (TaggedT tag m) where
get = lift get
put = lift . put
state = lift . state
instance MonadWriter w m => MonadWriter w (TaggedT tag m) where
writer = lift . writer
tell = lift . tell
listen = mapTaggedT listen
pass = mapTaggedT pass