{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Control.FX.Monad.Trans.WriteOnlyT (
WriteOnlyT(..)
, runWriteOnlyT
, Context(..)
, InputT(..)
, OutputT(..)
) where
import Data.Typeable (Typeable, typeOf)
import Control.Applicative (liftA2)
import Control.FX.EqIn
import Control.FX.Functor
import Control.FX.Monad
import Control.FX.Monad.Trans.Class
newtype WriteOnlyT
(mark :: * -> *)
(w :: *)
(m :: * -> *)
(a :: *)
= WriteOnlyT
{ unWriteOnlyT :: m (WriteOnly mark w a)
} deriving (Typeable)
deriving instance
( Show (m (WriteOnly mark w a))
) => Show (WriteOnlyT mark w m a)
instance
( Monoid w, Monad m, MonadIdentity mark
) => Functor (WriteOnlyT mark w m)
where
fmap
:: (a -> b)
-> WriteOnlyT mark w m a
-> WriteOnlyT mark w m b
fmap f = WriteOnlyT . fmap (fmap f) . unWriteOnlyT
instance
( Monoid w, Monad m, MonadIdentity mark
) => Applicative (WriteOnlyT mark w m)
where
pure
:: a
-> WriteOnlyT mark w m a
pure = WriteOnlyT . pure . pure
(<*>)
:: WriteOnlyT mark w m (a -> b)
-> WriteOnlyT mark w m a
-> WriteOnlyT mark w m b
(WriteOnlyT f) <*> (WriteOnlyT x) =
WriteOnlyT $ (liftA2 (<*>) f x)
instance
( Monoid w, Monad m, MonadIdentity mark
) => Monad (WriteOnlyT mark w m)
where
return
:: a
-> WriteOnlyT mark w m a
return = WriteOnlyT . return . return
(>>=)
:: WriteOnlyT mark w m a
-> (a -> WriteOnlyT mark w m b)
-> WriteOnlyT mark w m b
(WriteOnlyT x) >>= f =
WriteOnlyT $ do
WriteOnly (Pair w1 a) <- x
WriteOnly (Pair w2 b) <- unWriteOnlyT $ f a
return $ WriteOnly $ Pair (w1 <> w2) b
instance
( Monoid w, Central c, MonadIdentity mark
) => Commutant (WriteOnlyT mark w c)
where
commute
:: ( Applicative f )
=> WriteOnlyT mark w c (f a)
-> f (WriteOnlyT mark w c a)
commute =
fmap (WriteOnlyT) . commute . fmap commute . unWriteOnlyT
instance
( Monoid w, Central c, MonadIdentity mark
) => Central (WriteOnlyT mark w c)
instance
( Monoid w, MonadIdentity mark
) => MonadTrans (WriteOnlyT mark w)
where
lift
:: ( Monad m )
=> m a
-> WriteOnlyT mark w m a
lift x = WriteOnlyT $ (x >>= (return . pure))
instance
( Monoid w, MonadIdentity mark
) => MonadFunctor (WriteOnlyT mark w)
where
hoist
:: ( Monad m, Monad n )
=> (forall u. m u -> n u)
-> WriteOnlyT mark w m a
-> WriteOnlyT mark w n a
hoist f = WriteOnlyT . f . unWriteOnlyT
instance
( EqIn m, MonadIdentity mark, Eq w
) => EqIn (WriteOnlyT mark w m)
where
data Context (WriteOnlyT mark w m)
= WriteOnlyTCtx
{ unWriteOnlyTCtx :: (mark (), Context m)
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (WriteOnlyT mark w m)
-> WriteOnlyT mark w m a
-> WriteOnlyT mark w m a
-> Bool
eqIn (WriteOnlyTCtx (_,h)) x y =
eqIn h (unWriteOnlyT x) (unWriteOnlyT y)
deriving instance
( Show (mark ()), Show (Context m)
) => Show (Context (WriteOnlyT mark w m))
deriving instance
( Eq (mark ()), Eq (Context m)
) => Eq (Context (WriteOnlyT mark w m))
instance
( Monoid w, MonadIdentity mark
) => RunMonadTrans (WriteOnlyT mark w)
where
data InputT (WriteOnlyT mark w)
= WriteOnlyTIn
{ unWriteOnlyTIn :: mark ()
} deriving (Typeable)
data OutputT (WriteOnlyT mark w) a
= WriteOnlyTOut
{ unWriteOnlyTOut :: Pair (mark w) a
} deriving (Typeable)
runT
:: ( Monad m )
=> InputT (WriteOnlyT mark w)
-> WriteOnlyT mark w m a
-> m (OutputT (WriteOnlyT mark w) a)
runT _ (WriteOnlyT x) =
fmap (WriteOnlyTOut . bimap1 pure . unWriteOnly) x
runWriteOnlyT
:: ( Monad m, MonadIdentity mark, Monoid w )
=> WriteOnlyT mark w m a
-> m (Pair (mark w) a)
runWriteOnlyT =
fmap unWriteOnlyTOut . runT (WriteOnlyTIn $ pure ())
deriving instance
( Show (mark ())
) => Show (InputT (WriteOnlyT mark w))
deriving instance
( Eq (mark ())
) => Eq (InputT (WriteOnlyT mark w))
deriving instance
( Show a, Show (mark w)
) => Show (OutputT (WriteOnlyT mark w) a)
deriving instance
( Eq a, Eq (mark w)
) => Eq (OutputT (WriteOnlyT mark w) a)
instance
( Monoid w, MonadIdentity mark
) => Functor (OutputT (WriteOnlyT mark w))
where
fmap
:: (a -> b)
-> OutputT (WriteOnlyT mark w) a
-> OutputT (WriteOnlyT mark w) b
fmap f (WriteOnlyTOut x) =
WriteOnlyTOut (fmap f x)
instance
( Monoid w, MonadIdentity mark
) => Applicative (OutputT (WriteOnlyT mark w))
where
pure
:: a
-> OutputT (WriteOnlyT mark w) a
pure = WriteOnlyTOut . pure
(<*>)
:: OutputT (WriteOnlyT mark w) (a -> b)
-> OutputT (WriteOnlyT mark w) a
-> OutputT (WriteOnlyT mark w) b
(WriteOnlyTOut f) <*> (WriteOnlyTOut x) =
WriteOnlyTOut (f <*> x)
instance
( Monoid w, MonadIdentity mark
) => LiftCatch (WriteOnlyT mark w)
where
liftCatch
:: ( Monad m )
=> Catch e m (OutputT (WriteOnlyT mark w) a)
-> Catch e (WriteOnlyT mark w m) a
liftCatch catch x h = WriteOnlyT $
fmap (WriteOnly . bimap1 unwrap . unWriteOnlyTOut) $ catch
(fmap (WriteOnlyTOut . bimap1 pure . unWriteOnly) $ unWriteOnlyT x)
(\e -> fmap (WriteOnlyTOut . bimap1 pure . unWriteOnly) $ unWriteOnlyT $ h e)
instance
( Monoid w, MonadIdentity mark
, forall x. (Monoid x) => Monoid (mark x)
) => LiftDraft (WriteOnlyT mark w)
where
liftDraft
:: ( Monad m )
=> Draft w2 m (OutputT (WriteOnlyT mark w) a)
-> Draft w2 (WriteOnlyT mark w m) a
liftDraft draft =
WriteOnlyT . fmap (WriteOnly . bimap1 unwrap . unWriteOnlyTOut) . fmap commute
. draft . fmap (WriteOnlyTOut . bimap1 pure . unWriteOnly) . unWriteOnlyT
instance
( Monoid w, MonadIdentity mark
) => LiftLocal (WriteOnlyT mark w)
where
liftLocal
:: ( Monad m )
=> Local r m (OutputT (WriteOnlyT mark w) a)
-> Local r (WriteOnlyT mark w m) a
liftLocal local f =
WriteOnlyT . fmap (WriteOnly . bimap1 unwrap . unWriteOnlyTOut) . local f
. fmap (WriteOnlyTOut . bimap1 pure . unWriteOnly) . unWriteOnlyT
instance {-# OVERLAPPING #-}
( Monoid w, Monad m, MonadIdentity mark
) => MonadWriteOnly mark w (WriteOnlyT mark w m)
where
draft
:: WriteOnlyT mark w m a
-> WriteOnlyT mark w m (Pair (mark w) a)
draft = WriteOnlyT . fmap draft . unWriteOnlyT
tell
:: mark w
-> WriteOnlyT mark w m ()
tell = WriteOnlyT . return . tell
instance {-# OVERLAPPABLE #-}
( Monad m, MonadIdentity mark, MonadIdentity mark1
, MonadWriteOnly mark w m, Monoid w, Monoid w1
) => MonadWriteOnly mark w (WriteOnlyT mark1 w1 m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1
, MonadReadOnly mark r m, Monoid w
) => MonadReadOnly mark r (WriteOnlyT mark1 w m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1
, MonadState mark s m, Monoid w
) => MonadState mark s (WriteOnlyT mark1 w m)
instance
( Monad m, MonadIdentity mark1, Monoid w, MonadIdentity mark
, MonadHalt mark m
) => MonadHalt mark (WriteOnlyT mark1 w m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1, Monoid w
, MonadExcept mark e m
) => MonadExcept mark e (WriteOnlyT mark1 w m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1, Monoid w
, MonadPrompt mark p m
) => MonadPrompt mark p (WriteOnlyT mark1 w m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1
, MonadAppendOnly mark w m, Monoid w, Monoid w1
) => MonadAppendOnly mark w (WriteOnlyT mark1 w1 m)
instance
( Monad m, MonadIdentity mark, MonadIdentity mark1
, MonadWriteOnce mark w m, Monoid w1
) => MonadWriteOnce mark w (WriteOnlyT mark1 w1 m)