module Control.MFunctor (
MFunctor(..),
hoistK,
raise,
raiseK
) where
import Control.Monad.Trans.Class (MonadTrans(lift))
import Control.Monad.Trans.Identity (IdentityT, mapIdentityT)
import Control.Monad.Trans.Maybe (MaybeT, mapMaybeT)
import Control.Monad.Trans.Reader (ReaderT, mapReaderT)
import Control.Monad.Trans.RWS (RWST, mapRWST)
import qualified Control.Monad.Trans.State.Strict as StateStrict
import qualified Control.Monad.Trans.State.Lazy as StateLazy
import qualified Control.Monad.Trans.Writer.Strict as WriterStrict
import qualified Control.Monad.Trans.Writer.Lazy as WriterLazy
class MFunctor t where
hoist
:: (Monad m)
=> (forall a . m a -> n a)
-> t m b -> t n b
instance MFunctor IdentityT where
hoist nat = mapIdentityT nat
instance MFunctor MaybeT where
hoist nat = mapMaybeT nat
instance MFunctor (ReaderT r) where
hoist nat = mapReaderT nat
instance MFunctor (RWST r w s) where
hoist nat = mapRWST nat
instance MFunctor (StateStrict.StateT s) where
hoist nat = StateStrict.mapStateT nat
instance MFunctor (StateLazy.StateT s) where
hoist nat = StateLazy.mapStateT nat
instance MFunctor (WriterStrict.WriterT w) where
hoist nat = WriterStrict.mapWriterT nat
instance MFunctor (WriterLazy.WriterT w) where
hoist nat = WriterLazy.mapWriterT nat
hoistK
:: (Monad m, MFunctor t)
=> (forall a . m a -> n a)
-> (b' -> t m b)
-> (b' -> t n b)
hoistK k p a' = hoist k (p a')
raise :: (Monad m, MFunctor t1, MonadTrans t2) => t1 m r -> t1 (t2 m) r
raise = hoist lift
raiseK
:: (Monad m, MFunctor t1, MonadTrans t2) => (q -> t1 m r) -> (q -> t1 (t2 m) r)
raiseK = (hoist lift .)