monadology-0.2: src/Control/Monad/Ology/Specific/WithT.hs
module Control.Monad.Ology.Specific.WithT where
import Control.Monad.Ology.Data
import Control.Monad.Ology.General
import Import
type WithT :: forall k. (k -> Type) -> Type -> Type
newtype WithT m a = MkWithT
{ unWithT :: With m a
}
instance Functor (WithT m) where
fmap ab (MkWithT aff) = MkWithT $ \bf -> aff $ bf . ab
instance TransConstraint Functor WithT where
hasTransConstraint = Dict
instance Applicative (WithT m) where
pure a = MkWithT $ \af -> af a
MkWithT f <*> MkWithT x = MkWithT $ \bf -> f $ \ab -> x (bf . ab)
instance TransConstraint Applicative WithT where
hasTransConstraint = Dict
instance Monad (WithT m) where
return = pure
MkWithT m >>= f = MkWithT $ \bf -> m (\a -> unWithT (f a) bf)
instance TransConstraint Monad WithT where
hasTransConstraint = Dict
instance MonadTrans WithT where
lift m = MkWithT $ \af -> m >>= af
instance MonadIO m => MonadIO (WithT m) where
liftIO = lift . liftIO
instance TransConstraint MonadIO WithT where
hasTransConstraint = Dict
instance Semigroup a => Semigroup (WithT m a) where
(<>) = liftA2 (<>)
instance Monoid a => Monoid (WithT m a) where
mempty = pure mempty
instance MonadFix m => MonadFix (WithT m) where
mfix ama =
MkWithT $ \amr -> do
rec
(~(olda, r')) <-
unWithT (ama olda) $ \newa -> do
r <- amr newa
return (newa, r)
return r'
instance MonadException m => MonadException (WithT m) where
type Exc (WithT m) = Exc m
throwExc e = MkWithT $ \_ -> throwExc e
catchExc (MkWithT afrfr) cc = MkWithT $ \afr -> catchExc (afrfr afr) $ \e -> unWithT (cc e) afr
instance MonadThrow e m => MonadThrow e (WithT m) where
throw e = MkWithT $ \_ -> throw e
instance MonadCatch e m => MonadCatch e (WithT m) where
catch (MkWithT afrfr) cc = MkWithT $ \afr -> catch (afrfr afr) $ \e -> unWithT (cc e) afr
unpickWithT ::
forall m a. MonadCoroutine m
=> WithT m a
-> m (a, m ())
unpickWithT (MkWithT w) = unpickWith w
pickWithT ::
forall m a. Monad m
=> m (a, m ())
-> WithT m a
pickWithT mm = MkWithT $ pickWith mm
instance {-# OVERLAPPING #-} (MonadHoistIO m, MonadCoroutine m) => MonadHoistIO (WithT m) where
hoistIO f wma = pickWithT $ fmap (fmap $ hoistIO f) $ hoistIO f $ unpickWithT wma
mapWithT :: (m --> m) -> WithT m ()
mapWithT ff = MkWithT $ \uf -> ff $ uf ()
postWithT :: Monad m => m () -> WithT m ()
postWithT mu =
mapWithT $ \mr -> do
r <- mr
mu
return r
withTMap :: WithT m () -> m --> m
withTMap (MkWithT uff) f = uff $ \() -> f
execMapWithT :: Monad m => m (WithT m a) -> WithT m a
execMapWithT ffa =
MkWithT $ \af -> do
MkWithT aff <- ffa
aff af
withParamRef ::
forall m. Monad m
=> Param m --> Ref (WithT m)
withParamRef (param :: _ a) = let
refGet :: WithT m a
refGet =
MkWithT $ \afr -> do
a <- paramAsk param
afr a
refPut :: a -> WithT m ()
refPut a = MkWithT $ \ufr -> paramWith param a $ ufr ()
in MkRef {..}
liftWithT ::
forall t m. (MonadTransUnlift t, MonadTunnelIO m)
=> WithT m --> WithT (t m)
liftWithT (MkWithT aff) = MkWithT $ \atf -> liftWithUnlift $ \unlift -> aff $ unlift . atf