{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Control.FX.Monad.Trans.Trans.WriteOnlyTT (
WriteOnlyTT(..)
, runWriteOnlyTT
, Context(..)
, InputTT(..)
, OutputTT(..)
) where
import Data.Typeable (Typeable)
import Control.FX.EqIn
import Control.FX.Functor
import Control.FX.Monad
import Control.FX.Monad.Trans
import Control.FX.Monad.Trans.Trans.Class
newtype WriteOnlyTT
(mark :: * -> *)
(w :: *)
(t :: (* -> *) -> * -> *)
(m :: * -> *)
(a :: *)
= WriteOnlyTT
{ unWriteOnlyTT :: WriteOnlyT mark w (t m) a
} deriving
( Typeable, Functor, Applicative, Monad )
deriving instance
( Show (t m (WriteOnly mark w a))
) => Show (WriteOnlyTT mark w t m a)
instance
( MonadTrans t, MonadIdentity mark, Monoid w
) => MonadTrans (WriteOnlyTT mark w t)
where
lift
:: ( Monad m )
=> m a
-> WriteOnlyTT mark w t m a
lift = WriteOnlyTT . lift . lift
instance
( MonadFunctor t, MonadIdentity mark, Monoid w
) => MonadFunctor (WriteOnlyTT mark w t)
where
hoist
:: ( Monad m, Monad n )
=> (forall u. m u -> n u)
-> WriteOnlyTT mark w t m a
-> WriteOnlyTT mark w t n a
hoist f = WriteOnlyTT . hoist (hoist f) . unWriteOnlyTT
instance
( MonadIdentity mark, Monoid w
) => MonadTransTrans (WriteOnlyTT mark w)
where
liftT
:: ( Monad m, MonadTrans t )
=> t m a
-> WriteOnlyTT mark w t m a
liftT = WriteOnlyTT . lift
instance
( Monad m, MonadTrans t, MonadIdentity mark, Eq w
, EqIn (t m), Monoid w
) => EqIn (WriteOnlyTT mark w t m)
where
newtype Context (WriteOnlyTT mark w t m)
= WriteOnlyTTCtx
{ unWriteOnlyTTCtx :: (mark (), Context (t m))
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (WriteOnlyTT mark w t m)
-> WriteOnlyTT mark w t m a
-> WriteOnlyTT mark w t m a
-> Bool
eqIn (WriteOnlyTTCtx (v,h)) x y =
eqIn h
(fmap unWriteOnlyTTOut $ runTT (WriteOnlyTTIn v) x)
(fmap unWriteOnlyTTOut $ runTT (WriteOnlyTTIn v) y)
deriving instance
( Eq (mark ()), Eq (Context (t m))
) => Eq (Context (WriteOnlyTT mark w t m))
deriving instance
( Show (mark ()), Show (Context (t m))
) => Show (Context (WriteOnlyTT mark w t m))
instance
( MonadIdentity mark, Monoid w
) => RunMonadTransTrans (WriteOnlyTT mark w)
where
newtype InputTT (WriteOnlyTT mark w) m
= WriteOnlyTTIn
{ unWriteOnlyTTIn :: mark ()
} deriving (Typeable)
newtype OutputTT (WriteOnlyTT mark w) a
= WriteOnlyTTOut
{ unWriteOnlyTTOut :: Pair (mark w) a
} deriving (Typeable)
runTT
:: ( Monad m, MonadTrans t )
=> InputTT (WriteOnlyTT mark w) m
-> WriteOnlyTT mark w t m a
-> t m (OutputTT (WriteOnlyTT mark w) a)
runTT (WriteOnlyTTIn w) =
fmap (WriteOnlyTTOut . unWriteOnlyTOut)
. runT (WriteOnlyTIn w) . unWriteOnlyTT
deriving instance
( Eq (mark ())
) => Eq (InputTT (WriteOnlyTT mark w) m)
deriving instance
( Show (mark ())
) => Show (InputTT (WriteOnlyTT mark w) m)
deriving instance
( Eq (mark w), Eq a
) => Eq (OutputTT (WriteOnlyTT mark w) a)
deriving instance
( Show (mark w), Show a
) => Show (OutputTT (WriteOnlyTT mark w) a)
runWriteOnlyTT
:: ( MonadIdentity mark, Monad m, MonadTrans t, Monoid w )
=> mark ()
-> WriteOnlyTT mark w t m a
-> t m (Pair (mark w) a)
runWriteOnlyTT w = fmap unWriteOnlyTTOut . runTT (WriteOnlyTTIn w)
instance
( MonadIdentity mark, Monoid w
) => LiftCatchT (WriteOnlyTT mark w)
where
liftCatchT
:: forall m t e
. ( Monad m, MonadTrans t )
=> (forall x. Catch e (t m) (OutputTT (WriteOnlyTT mark w) x))
-> (forall x. Catch e (WriteOnlyTT mark w t m) x)
liftCatchT catch x h =
let
catch' :: Catch e (t m) (OutputT (WriteOnlyT mark w) x)
catch' y g =
fmap (WriteOnlyTOut . unWriteOnlyTTOut) $ catch
(fmap (WriteOnlyTTOut . unWriteOnlyTOut) y)
(fmap (WriteOnlyTTOut . unWriteOnlyTOut) . g)
in
WriteOnlyTT $ liftCatch catch' (unWriteOnlyTT x) (unWriteOnlyTT . h)
instance
( MonadIdentity mark, Monoid w
) => LiftDraftT (WriteOnlyTT mark w)
where
liftDraftT
:: forall m t w w2
. ( Monad m, MonadTrans t, Monoid w, Monoid w2 )
=> (forall x. Draft w2 (t m) (OutputTT (WriteOnlyTT mark w) x))
-> (forall x. Draft w2 (WriteOnlyTT mark w t m) x)
liftDraftT draft =
let
draft' :: Draft w2 (t m) (OutputT (WriteOnlyT mark w) x)
draft' =
fmap (fmap (WriteOnlyTOut . unWriteOnlyTTOut))
. draft . fmap (WriteOnlyTTOut . unWriteOnlyTOut)
in
WriteOnlyTT . liftDraft draft' . unWriteOnlyTT
instance
( MonadIdentity mark, Monoid w
) => LiftLocalT (WriteOnlyTT mark w)
where
liftLocalT
:: forall m t r
. ( Monad m, MonadTrans t )
=> (forall x. Local r (t m) (OutputTT (WriteOnlyTT mark w) x))
-> (forall x. Local r (WriteOnlyTT mark w t m) x)
liftLocalT local f =
let
local' :: Local r (t m) (OutputT (WriteOnlyT mark w) x)
local' g =
fmap (WriteOnlyTOut . unWriteOnlyTTOut)
. local g . fmap (WriteOnlyTTOut . unWriteOnlyTOut)
in
WriteOnlyTT . liftLocal local' f . unWriteOnlyTT
instance {-# OVERLAPPING #-}
( Monad m, MonadTrans t, MonadIdentity mark, Monoid w
) => MonadWriteOnly mark w (WriteOnlyTT mark w t m)
where
tell
:: mark w
-> WriteOnlyTT mark w t m ()
tell = WriteOnlyTT . tell
draft
:: WriteOnlyTT mark w t m a
-> WriteOnlyTT mark w t m (Pair (mark w) a)
draft = WriteOnlyTT . draft . unWriteOnlyTT
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w, Monoid w1
, forall x. (Monad x) => MonadWriteOnly mark w (t x)
) => MonadWriteOnly mark w (WriteOnlyTT mark1 w1 t m)
where
tell
:: mark w
-> WriteOnlyTT mark1 w1 t m ()
tell = WriteOnlyTT . lift . tell
draft
:: WriteOnlyTT mark1 w1 t m a
-> WriteOnlyTT mark1 w1 t m (Pair (mark w) a)
draft = liftDraftT draft
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w, Monoid w1
, forall x. (Monad x) => MonadAppendOnly mark w (t x)
) => MonadAppendOnly mark w (WriteOnlyTT mark1 w1 t m)
where
jot
:: mark w
-> WriteOnlyTT mark1 w1 t m ()
jot = WriteOnlyTT . lift . jot
look
:: WriteOnlyTT mark1 w1 t m (mark w)
look = WriteOnlyTT $ lift look
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w1
, forall x. (Monad x) => MonadWriteOnce mark w (t x)
) => MonadWriteOnce mark w (WriteOnlyTT mark1 w1 t m)
where
etch
:: mark w
-> WriteOnlyTT mark1 w1 t m Bool
etch = WriteOnlyTT . lift . etch
press
:: WriteOnlyTT mark1 w1 t m (Maybe (mark w))
press = WriteOnlyTT $ lift press
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w
, forall x. (Monad x) => MonadState mark s (t x)
) => MonadState mark s (WriteOnlyTT mark1 w t m)
where
get
:: WriteOnlyTT mark1 w t m (mark s)
get = WriteOnlyTT $ lift get
put
:: mark s
-> WriteOnlyTT mark1 w t m ()
put = WriteOnlyTT . lift . put
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w
, forall x. (Monad x) => MonadExcept mark e (t x)
) => MonadExcept mark e (WriteOnlyTT mark1 w t m)
where
throw
:: mark e
-> WriteOnlyTT mark1 w t m a
throw = WriteOnlyTT . lift . throw
catch
:: WriteOnlyTT mark1 w t m a
-> (mark e -> WriteOnlyTT mark1 w t m a)
-> WriteOnlyTT mark1 w t m a
catch = liftCatchT catch
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w
, forall x. (Monad x) => MonadReadOnly mark r (t x)
) => MonadReadOnly mark r (WriteOnlyTT mark1 w t m)
where
ask
:: WriteOnlyTT mark1 w t m (mark r)
ask = WriteOnlyTT $ lift ask
local
:: (mark r -> mark r)
-> WriteOnlyTT mark1 w t m a
-> WriteOnlyTT mark1 w t m a
local = liftLocalT local
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w
, forall x. (Monad x) => MonadPrompt mark p (t x)
) => MonadPrompt mark p (WriteOnlyTT mark1 w t m)
where
prompt
:: mark (p a)
-> WriteOnlyTT mark1 w t m (mark a)
prompt = WriteOnlyTT . lift . prompt
instance
( Monad m, MonadTrans t, MonadIdentity mark1, Monoid w, MonadIdentity mark
, forall x. (Monad x) => MonadHalt mark (t x)
) => MonadHalt mark (WriteOnlyTT mark1 w t m)
where
halt
:: mark ()
-> WriteOnlyTT mark1 w t m a
halt = WriteOnlyTT . lift . halt