{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Control.FX.Monad.Trans.Trans.AppendOnlyTT (
AppendOnlyTT(..)
, runAppendOnlyTT
, 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 AppendOnlyTT
(mark :: * -> *)
(w :: *)
(t :: (* -> *) -> * -> *)
(m :: * -> *)
(a :: *)
= AppendOnlyTT
{ unAppendOnlyTT :: AppendOnlyT mark w (t m) a
} deriving
( Show, Typeable, Functor, Applicative, Monad )
instance
( MonadTrans t, MonadIdentity mark, Monoid w
) => MonadTrans (AppendOnlyTT mark w t)
where
lift
:: ( Monad m )
=> m a
-> AppendOnlyTT mark w t m a
lift = AppendOnlyTT . lift . lift
instance
( MonadFunctor t, MonadIdentity mark, Monoid w
) => MonadFunctor (AppendOnlyTT mark w t)
where
hoist
:: ( Monad m, Monad n )
=> (forall u. m u -> n u)
-> AppendOnlyTT mark w t m a
-> AppendOnlyTT mark w t n a
hoist f = AppendOnlyTT . hoist (hoist f) . unAppendOnlyTT
instance
( MonadIdentity mark, Monoid w
) => MonadTransTrans (AppendOnlyTT mark w)
where
liftT
:: ( Monad m, MonadTrans t )
=> t m a
-> AppendOnlyTT mark w t m a
liftT = AppendOnlyTT . lift
instance
( Monad m, MonadTrans t, MonadIdentity mark, Eq w
, EqIn (t m), Monoid w
) => EqIn (AppendOnlyTT mark w t m)
where
newtype Context (AppendOnlyTT mark w t m)
= AppendOnlyTTCtx
{ unAppendOnlyTTCtx :: (mark (), Context (t m))
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (AppendOnlyTT mark w t m)
-> AppendOnlyTT mark w t m a
-> AppendOnlyTT mark w t m a
-> Bool
eqIn (AppendOnlyTTCtx (v,h)) x y =
eqIn h
(fmap unAppendOnlyTTOut $ runTT (AppendOnlyTTIn v) x)
(fmap unAppendOnlyTTOut $ runTT (AppendOnlyTTIn v) y)
deriving instance
( Eq (mark ()), Eq (Context (t m))
) => Eq (Context (AppendOnlyTT mark w t m))
deriving instance
( Show (mark ()), Show (Context (t m))
) => Show (Context (AppendOnlyTT mark w t m))
instance
( MonadIdentity mark, Monoid w
) => RunMonadTransTrans (AppendOnlyTT mark w)
where
newtype InputTT (AppendOnlyTT mark w) m
= AppendOnlyTTIn
{ unAppendOnlyTTIn :: mark ()
} deriving (Typeable)
newtype OutputTT (AppendOnlyTT mark w) a
= AppendOnlyTTOut
{ unAppendOnlyTTOut :: Pair (mark w) a
} deriving (Typeable)
runTT
:: ( Monad m, MonadTrans t )
=> InputTT (AppendOnlyTT mark w) m
-> AppendOnlyTT mark w t m a
-> t m (OutputTT (AppendOnlyTT mark w) a)
runTT (AppendOnlyTTIn w) =
fmap (AppendOnlyTTOut . unAppendOnlyTOut)
. runT (AppendOnlyTIn w) . unAppendOnlyTT
deriving instance
( Eq (mark ())
) => Eq (InputTT (AppendOnlyTT mark w) m)
deriving instance
( Show (mark ())
) => Show (InputTT (AppendOnlyTT mark w) m)
deriving instance
( Eq (mark w), Eq a
) => Eq (OutputTT (AppendOnlyTT mark w) a)
deriving instance
( Show (mark w), Show a
) => Show (OutputTT (AppendOnlyTT mark w) a)
runAppendOnlyTT
:: ( MonadIdentity mark, Monad m, MonadTrans t, Monoid w )
=> mark ()
-> AppendOnlyTT mark w t m a
-> t m (Pair (mark w) a)
runAppendOnlyTT w = fmap unAppendOnlyTTOut . runTT (AppendOnlyTTIn w)
instance
( MonadIdentity mark, Monoid w
) => LiftCatchT (AppendOnlyTT mark w)
where
liftCatchT
:: forall m t e
. ( Monad m, MonadTrans t )
=> (forall x. Catch e (t m) (OutputTT (AppendOnlyTT mark w) x))
-> (forall x. Catch e (AppendOnlyTT mark w t m) x)
liftCatchT catch x h =
let
catch' :: Catch e (t m) (OutputT (AppendOnlyT mark w) x)
catch' y g =
fmap (AppendOnlyTOut . unAppendOnlyTTOut) $ catch
(fmap (AppendOnlyTTOut . unAppendOnlyTOut) y)
(fmap (AppendOnlyTTOut . unAppendOnlyTOut) . g)
in
AppendOnlyTT $ liftCatch catch' (unAppendOnlyTT x) (unAppendOnlyTT . h)
instance
( MonadIdentity mark, Monoid w
) => LiftDraftT (AppendOnlyTT mark w)
where
liftDraftT
:: forall m t w1
. ( Monad m, MonadTrans t, Monoid w1 )
=> (forall x. Draft w1 (t m) (OutputTT (AppendOnlyTT mark w) x))
-> (forall x. Draft w1 (AppendOnlyTT mark w t m) x)
liftDraftT draft =
let
draft' :: Draft w1 (t m) (OutputT (AppendOnlyT mark w) x)
draft' =
fmap (fmap (AppendOnlyTOut . unAppendOnlyTTOut))
. draft . fmap (AppendOnlyTTOut . unAppendOnlyTOut)
in
AppendOnlyTT . liftDraft draft' . unAppendOnlyTT
instance
( MonadIdentity mark, Monoid w
) => LiftLocalT (AppendOnlyTT mark w)
where
liftLocalT
:: forall m t r
. ( Monad m, MonadTrans t )
=> (forall x. Local r (t m) (OutputTT (AppendOnlyTT mark w) x))
-> (forall x. Local r (AppendOnlyTT mark w t m) x)
liftLocalT local f =
let
local' :: Local r (t m) (OutputT (AppendOnlyT mark w) x)
local' g =
fmap (AppendOnlyTOut . unAppendOnlyTTOut)
. local g . fmap (AppendOnlyTTOut . unAppendOnlyTOut)
in
AppendOnlyTT . liftLocal local' f . unAppendOnlyTT
instance {-# OVERLAPPING #-}
( Monad m, MonadTrans t, MonadIdentity mark, Monoid w
) => MonadAppendOnly mark w (AppendOnlyTT mark w t m)
where
look
:: AppendOnlyTT mark w t m (mark w)
look = AppendOnlyTT look
jot
:: mark w
-> AppendOnlyTT mark w t m ()
jot = AppendOnlyTT . jot
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadAppendOnly mark w (t x), Monoid w1, Monoid w
) => MonadAppendOnly mark w (AppendOnlyTT mark1 w1 t m)
where
look
:: AppendOnlyTT mark1 w1 t m (mark w)
look = AppendOnlyTT $ lift look
jot
:: mark w
-> AppendOnlyTT mark1 w1 t m ()
jot = AppendOnlyTT . lift . jot
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadWriteOnce mark w (t x), Monoid w1
) => MonadWriteOnce mark w (AppendOnlyTT mark1 w1 t m)
where
press
:: AppendOnlyTT mark1 w1 t m (Maybe (mark w))
press = AppendOnlyTT $ lift press
etch
:: mark w
-> AppendOnlyTT mark1 w1 t m Bool
etch = AppendOnlyTT . lift . etch
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadState mark s (t x), Monoid w
) => MonadState mark s (AppendOnlyTT mark1 w t m)
where
get
:: AppendOnlyTT mark1 w t m (mark s)
get = AppendOnlyTT $ lift get
put
:: mark s
-> AppendOnlyTT mark1 w t m ()
put = AppendOnlyTT . lift . put
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadExcept mark e (t x), Monoid w
) => MonadExcept mark e (AppendOnlyTT mark1 w t m)
where
throw
:: mark e
-> AppendOnlyTT mark1 w t m a
throw = AppendOnlyTT . lift . throw
catch
:: AppendOnlyTT mark1 w t m a
-> (mark e -> AppendOnlyTT mark1 w t m a)
-> AppendOnlyTT mark1 w t m a
catch = liftCatchT catch
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1, Monoid w
, forall x. (Monad x) => MonadWriteOnly mark w (t x), Monoid w1
) => MonadWriteOnly mark w (AppendOnlyTT mark1 w1 t m)
where
tell
:: mark w
-> AppendOnlyTT mark1 w1 t m ()
tell = AppendOnlyTT . lift . tell
draft
:: AppendOnlyTT mark1 w1 t m a
-> AppendOnlyTT mark1 w1 t m (Pair (mark w) a)
draft = liftDraftT draft
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadReadOnly mark r (t x), Monoid w
) => MonadReadOnly mark r (AppendOnlyTT mark1 w t m)
where
ask
:: AppendOnlyTT mark1 w t m (mark r)
ask = AppendOnlyTT $ lift ask
local
:: (mark r -> mark r)
-> AppendOnlyTT mark1 w t m a
-> AppendOnlyTT mark1 w t m a
local = liftLocalT local
instance
( Monad m, MonadTrans t, MonadIdentity mark, MonadIdentity mark1
, forall x. (Monad x) => MonadPrompt mark p (t x), Monoid w
) => MonadPrompt mark p (AppendOnlyTT mark1 w t m)
where
prompt
:: mark (p a)
-> AppendOnlyTT mark1 w t m (mark a)
prompt = AppendOnlyTT . lift . prompt
instance
( Monad m, MonadTrans t, MonadIdentity mark1, MonadIdentity mark, Monoid w
, forall x. (Monad x) => MonadHalt mark (t x)
) => MonadHalt mark (AppendOnlyTT mark1 w t m)
where
halt
:: mark ()
-> AppendOnlyTT mark1 w t m a
halt = AppendOnlyTT . lift . halt