monadology-0.2: src/Control/Monad/Ology/Specific/WriterT.hs
{-# OPTIONS -fno-warn-orphans #-}
module Control.Monad.Ology.Specific.WriterT
( module Control.Monad.Trans.Writer
, module Control.Monad.Ology.Specific.WriterT
) where
import Control.Monad.Ology.General
import Control.Monad.Trans.Writer hiding (liftCallCC, liftCatch)
import Import
collect :: (Monad m, Monoid w) => WriterT w m a -> WriterT w m (a, w)
collect wmr = censor (\_ -> mempty) $ listen wmr
evalWriterT :: Monad m => WriterT w m a -> m a
evalWriterT wma = fmap fst $ runWriterT wma
instance Monoid w => TransConstraint Functor (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint Applicative (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint Monad (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint MonadIO (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint MonadFail (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint MonadFix (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => TransConstraint MonadPlus (WriterT w) where
hasTransConstraint = Dict
instance (MonadExtract m, Monoid w) => MonadExtract (WriterT w m) where
mToValue (WriterT maw) = fst $ mToValue maw
instance Monoid w => TransConstraint MonadExtract (WriterT w) where
hasTransConstraint = Dict
instance (MonadInner m, Monoid w) => MonadInner (WriterT w m) where
retrieveInner (WriterT maw) = fmap fst $ retrieveInner maw
instance Monoid w => TransConstraint MonadInner (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => MonadTransCoerce (WriterT w) where
transCoerce = Dict
instance (Monoid w, MonadException m) => MonadException (WriterT w m) where
type Exc (WriterT w m) = Exc m
throwExc e = lift $ throwExc e
catchExc tma handler = tunnel $ \unlift -> catchExc (unlift tma) $ \e -> unlift $ handler e
instance Monoid w => TransConstraint MonadException (WriterT w) where
hasTransConstraint = Dict
instance (MonadThrow e m, Monoid w) => MonadThrow e (WriterT w m) where
throw e = lift $ throw e
instance Monoid w => TransConstraint (MonadThrow e) (WriterT w) where
hasTransConstraint = Dict
instance (MonadCatch e m, Monoid w) => MonadCatch e (WriterT w m) where
catch ma handler = tunnel $ \unlift -> catch (unlift ma) $ \e -> unlift $ handler e
instance Monoid w => TransConstraint (MonadCatch e) (WriterT w) where
hasTransConstraint = Dict
instance Monoid w => MonadTransHoist (WriterT w) where
hoist = tunnelHoist
instance Monoid w => MonadTransTunnel (WriterT w) where
type Tunnel (WriterT w) = (,) w
tunnel call = WriterT $ fmap swap $ call $ \(WriterT mrs) -> fmap swap $ mrs
instance Monoid w => MonadTransUnlift (WriterT w) where
liftWithUnlift call = do
var <- liftIO $ newMVar mempty
r <-
lift $
call $ \(WriterT mrs) -> do
(r, output) <- mrs
liftIO $ modifyMVar_ var $ \oldoutput -> return $ mappend oldoutput output
return r
totaloutput <- liftIO $ takeMVar var
tell totaloutput
return r