monadology-0.1: src/Control/Monad/Ology/Specific/TransformT.hs
module Control.Monad.Ology.Specific.TransformT where
import Control.Monad.Ology.Data
import Control.Monad.Ology.General
import Import
type TransformT :: forall k. (k -> Type) -> Type -> Type
newtype TransformT f a = MkTransformT
{ unTransformT :: forall r. (a -> f r) -> f r
}
instance Functor (TransformT f) where
fmap ab (MkTransformT aff) = MkTransformT $ \bf -> aff $ bf . ab
instance TransConstraint Functor TransformT where
hasTransConstraint = Dict
instance Applicative (TransformT f) where
pure a = MkTransformT $ \af -> af a
MkTransformT f <*> MkTransformT x = MkTransformT $ \bf -> f $ \ab -> x (bf . ab)
instance TransConstraint Applicative TransformT where
hasTransConstraint = Dict
instance Monad (TransformT f) where
return = pure
MkTransformT m >>= f = MkTransformT $ \bf -> m (\a -> unTransformT (f a) bf)
instance TransConstraint Monad TransformT where
hasTransConstraint = Dict
instance MonadTrans TransformT where
lift m = MkTransformT $ \af -> m >>= af
instance MonadIO m => MonadIO (TransformT m) where
liftIO = lift . liftIO
instance TransConstraint MonadIO TransformT where
hasTransConstraint = Dict
instance Semigroup a => Semigroup (TransformT f a) where
(<>) = liftA2 (<>)
instance Monoid a => Monoid (TransformT f a) where
mempty = pure mempty
instance MonadFix m => MonadFix (TransformT m) where
mfix ama =
MkTransformT $ \amr -> do
rec
(~(olda, r')) <-
unTransformT (ama olda) $ \newa -> do
r <- amr newa
return (newa, r)
return r'
mapTransformT :: (f --> f) -> TransformT f ()
mapTransformT ff = MkTransformT $ \uf -> ff $ uf ()
postTransformT :: Monad m => m () -> TransformT m ()
postTransformT mu =
mapTransformT $ \mr -> do
r <- mr
mu
return r
transformTMap :: TransformT f () -> f --> f
transformTMap (MkTransformT uff) f = uff $ \() -> f
execMapTransformT :: Monad f => f (TransformT f a) -> TransformT f a
execMapTransformT ffa =
MkTransformT $ \af -> do
MkTransformT aff <- ffa
aff af
transformParamRef ::
forall m. Monad m
=> Param m --> Ref (TransformT m)
transformParamRef (param :: _ a) = let
refGet :: TransformT m a
refGet =
MkTransformT $ \afr -> do
a <- paramAsk param
afr a
refPut :: a -> TransformT m ()
refPut a = MkTransformT $ \ufr -> paramWith param a $ ufr ()
in MkRef {..}
liftTransformT ::
forall t m. (MonadTransUnlift t, MonadTunnelIOInner m)
=> TransformT m --> TransformT (t m)
liftTransformT (MkTransformT aff) = MkTransformT $ \atf -> liftWithUnlift $ \unlift -> aff $ unlift . atf