{-# LANGUAGE Rank2Types #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE MultiParamTypeClasses #-}
module Control.FX.Monad.Trans.Trans.OverTT (
OverableT(..)
, OverTT(..)
, runOverTT
, Context(..)
, InputTT(..)
, OutputTT(..)
) where
import Data.Typeable (Typeable, typeOf)
import Control.Monad (ap)
import Control.FX.EqIn
import Control.FX.Functor
import Control.FX.Monad
import Control.FX.Monad.Trans
import Control.FX.Monad.Trans.Trans.Class
class
( MonadTrans v
) => OverableT v
where
data
OverTT
(v :: (* -> *) -> * -> *)
(u :: ((* -> *) -> * -> *) -> (* -> *) -> * -> *)
(t :: (* -> *) -> * -> *)
(m :: * -> *)
(a :: *)
toOverTT
:: v (u t m) a
-> OverTT v u t m a
unOverTT
:: OverTT v u t m a
-> v (u t m) a
instance
OverableT IdentityT
where
newtype (OverTT IdentityT u t m a) =
OverTT_IdentityT
{ unOverTT_IdentityT :: IdentityT (u t m) a
} deriving (Typeable)
toOverTT = OverTT_IdentityT
unOverTT = unOverTT_IdentityT
instance
( MonadIdentity mark
) => OverableT (HaltT mark)
where
newtype (OverTT (HaltT mark) u t m a) =
OverTT_HaltT
{ unOverTT_HaltT :: HaltT mark (u t m) a
} deriving (Typeable)
toOverTT = OverTT_HaltT
unOverTT = unOverTT_HaltT
instance
( MonadIdentity mark
) => OverableT (StateT mark s)
where
newtype (OverTT (StateT mark s) u t m a) =
OverTT_StateT
{ unOverTT_StateT :: StateT mark s (u t m) a
} deriving (Typeable)
toOverTT = OverTT_StateT
unOverTT = unOverTT_StateT
instance
( MonadIdentity mark
) => OverableT (ReadOnlyT mark r)
where
newtype (OverTT (ReadOnlyT mark r) u t m a) =
OverTT_ReadOnlyT
{ unOverTT_ReadOnlyT :: ReadOnlyT mark r (u t m) a
} deriving (Typeable)
toOverTT = OverTT_ReadOnlyT
unOverTT = unOverTT_ReadOnlyT
instance
( MonadIdentity mark, Monoid w
) => OverableT (WriteOnlyT mark w)
where
newtype (OverTT (WriteOnlyT mark w) u t m a) =
OverTT_WriteOnlyT
{ unOverTT_WriteOnlyT :: WriteOnlyT mark w (u t m) a
} deriving (Typeable)
toOverTT = OverTT_WriteOnlyT
unOverTT = unOverTT_WriteOnlyT
instance
( MonadIdentity mark
) => OverableT (WriteOnceT mark w)
where
newtype (OverTT (WriteOnceT mark w) u t m a) =
OverTT_WriteOnceT
{ unOverTT_WriteOnceT :: WriteOnceT mark w (u t m) a
} deriving (Typeable)
toOverTT = OverTT_WriteOnceT
unOverTT = unOverTT_WriteOnceT
instance
( MonadIdentity mark, Monoid w
) => OverableT (AppendOnlyT mark w)
where
newtype (OverTT (AppendOnlyT mark w) u t m a) =
OverTT_AppendOnlyT
{ unOverTT_AppendOnlyT :: AppendOnlyT mark w (u t m) a
} deriving (Typeable)
toOverTT = OverTT_AppendOnlyT
unOverTT = unOverTT_AppendOnlyT
instance
( MonadIdentity mark
) => OverableT (ExceptT mark e)
where
newtype (OverTT (ExceptT mark e) u t m a) =
OverTT_ExceptT
{ unOverTT_ExceptT :: ExceptT mark e (u t m) a
} deriving (Typeable)
toOverTT = OverTT_ExceptT
unOverTT = unOverTT_ExceptT
instance
( Show (v (u t m) a), OverableT v
) => Show (OverTT v u t m a)
where
show = show . unOverTT
instance
( Monad m, MonadTrans t, MonadTrans v
, MonadTransTrans u, OverableT v
) => Functor (OverTT v u t m)
where
fmap
:: (a -> b)
-> OverTT v u t m a
-> OverTT v u t m b
fmap f = toOverTT . fmap f . unOverTT
instance
( Monad m, MonadTrans t, MonadTrans v
, MonadTransTrans u, OverableT v
) => Applicative (OverTT v u t m)
where
pure
:: a
-> OverTT v u t m a
pure = return
(<*>)
:: OverTT v u t m (a -> b)
-> OverTT v u t m a
-> OverTT v u t m b
(<*>) = ap
instance
( Monad m, MonadTrans t, MonadTrans v
, MonadTransTrans u, OverableT v
) => Monad (OverTT v u t m)
where
return
:: a
-> OverTT v u t m a
return = toOverTT . return
(>>=)
:: OverTT v u t m a
-> (a -> OverTT v u t m b)
-> OverTT v u t m b
x >>= f =
toOverTT $ (unOverTT x) >>= (unOverTT . f)
instance
( MonadTrans t, MonadTrans v
, MonadTransTrans u, OverableT v
) => MonadTrans (OverTT v u t)
where
lift
:: ( Monad m )
=> m a
-> OverTT v u t m a
lift = toOverTT . lift . lift
instance
( MonadTrans v, MonadTransTrans u, OverableT v
) => MonadTransTrans (OverTT v u)
where
liftT
:: ( Monad m, MonadTrans t )
=> t m a
-> OverTT v u t m a
liftT = toOverTT . lift . liftT
instance
( MonadIdentity (v (u t m))
, OverableT v, Eq a
) => Eq (OverTT v u t m a)
where
(==)
:: OverTT v u t m a
-> OverTT v u t m a
-> Bool
x == y =
(==)
(unwrap $ unOverTT x)
(unwrap $ unOverTT y)
instance
( MonadIdentity (v (u t m))
, OverableT v, Semigroup a
) => Semigroup (OverTT v u t m a)
where
(<>)
:: OverTT v u t m a
-> OverTT v u t m a
-> OverTT v u t m a
x <> y =
toOverTT $ pure $ (<>)
(unwrap $ unOverTT x)
(unwrap $ unOverTT y)
instance
( MonadIdentity (v (u t m))
, OverableT v, Monoid a
) => Monoid (OverTT v u t m a)
where
mempty
:: OverTT v u t m a
mempty = toOverTT $ pure mempty
instance
( Monad m, MonadTrans t, MonadTrans v, MonadTransTrans u
, RunMonadTransTrans u, RunMonadTrans v, OverableT v
, forall x. (Eq x) => Eq (OutputTT u (OutputT v x))
, EqIn (t m)
) => EqIn (OverTT v u t m)
where
newtype Context (OverTT v u t m)
= OverTTCtx
{ unOverTTCtx :: ((InputTT u m, InputT v), Context (t m))
} deriving (Typeable)
eqIn
:: (Eq a)
=> Context (OverTT v u t m)
-> OverTT v u t m a
-> OverTT v u t m a
-> Bool
eqIn (OverTTCtx (k,h)) x y =
eqIn h
(fmap unOverTTOut $ runTT (OverTTIn k) x)
(fmap unOverTTOut $ runTT (OverTTIn k) y)
deriving instance
( Eq (InputTT u m), Eq (InputT v), Eq (Context (t m))
) => Eq (Context (OverTT v u t m))
deriving instance
( Show (InputTT u m), Show (InputT v), Show (Context (t m))
) => Show (Context (OverTT v u t m))
instance
( RunMonadTransTrans u, RunMonadTrans v
, MonadTrans v, OverableT v
) => RunMonadTransTrans (OverTT v u)
where
newtype InputTT (OverTT v u) m
= OverTTIn
{ unOverTTIn :: (InputTT u m, InputT v)
} deriving (Typeable)
newtype OutputTT (OverTT v u) a
= OverTTOut
{ unOverTTOut :: Compose (OutputTT u) (OutputT v) a
} deriving (Typeable)
runTT
:: ( Monad m, MonadTrans t )
=> InputTT (OverTT v u) m
-> OverTT v u t m a
-> t m (OutputTT (OverTT v u) a)
runTT (OverTTIn (z1,z2)) =
fmap (OverTTOut . Compose) . runTT z1 . runT z2 . unOverTT
deriving instance
( Eq (InputTT u m), Eq (InputT v)
) => Eq (InputTT (OverTT v u) m)
deriving instance
( Show (InputTT u m), Show (InputT v)
) => Show (InputTT (OverTT v u) m)
deriving instance
( Eq (OutputTT u a), Eq (OutputTT u (OutputT v a))
) => Eq (OutputTT (OverTT v u) a)
deriving instance
( Show (OutputTT u a) , Show (OutputTT u (OutputT v a))
) => Show (OutputTT (OverTT v u) a)
runOverTT
:: ( RunMonadTransTrans u, RunMonadTrans v, OverableT v
, Monad m, MonadTrans t, MonadTrans v )
=> InputTT u m
-> InputT v
-> OverTT v u t m a
-> t m (OutputTT u (OutputT v a))
runOverTT z1 z2 =
fmap (unCompose . unOverTTOut) . runTT (OverTTIn (z1,z2))
instance
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadIdentity (v (u t m))
) => MonadIdentity (OverTT v u t m)
where
unwrap
:: OverTT v u t m a
-> a
unwrap = unwrap . unOverTT
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t
, MonadTransTrans u, MonadIdentity mark
) => MonadExcept mark e (OverTT (ExceptT mark e) u t m)
where
throw
:: mark e
-> OverTT (ExceptT mark e) u t m a
throw = toOverTT . throw
catch
:: OverTT (ExceptT mark e) u t m a
-> (mark e -> OverTT (ExceptT mark e) u t m a)
-> OverTT (ExceptT mark e) u t m a
catch x h = toOverTT $ catch (unOverTT x) (unOverTT . h)
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadIdentity mark, LiftCatch v
, forall x. (Monad x) => MonadExcept mark e (u t x)
) => MonadExcept mark e (OverTT v u t m)
where
throw
:: mark e
-> OverTT v u t m a
throw = toOverTT . lift . throw
catch
:: OverTT v u t m a
-> (mark e -> OverTT v u t m a)
-> OverTT v u t m a
catch x h = toOverTT $ liftCatch catch (unOverTT x) (unOverTT . h)
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t, Monoid w
, MonadTransTrans u, MonadIdentity mark
) => MonadWriteOnly mark w (OverTT (WriteOnlyT mark w) u t m)
where
tell
:: mark w
-> OverTT (WriteOnlyT mark w) u t m ()
tell = toOverTT . tell
draft
:: OverTT (WriteOnlyT mark w) u t m a
-> OverTT (WriteOnlyT mark w) u t m (Pair (mark w) a)
draft = toOverTT . draft . unOverTT
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, Monoid w, LiftDraft v
, MonadTransTrans u, MonadIdentity mark, OverableT v
, forall x. (Monad x) => MonadWriteOnly mark w (u t x)
) => MonadWriteOnly mark w (OverTT v u t m)
where
tell
:: mark w
-> OverTT v u t m ()
tell = toOverTT . lift . tell
draft
:: OverTT v u t m a
-> OverTT v u t m (Pair (mark w) a)
draft = toOverTT . liftDraft draft . unOverTT
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t, Monoid w
, MonadTransTrans u, MonadIdentity mark
) => MonadAppendOnly mark w (OverTT (AppendOnlyT mark w) u t m)
where
jot
:: mark w
-> OverTT (AppendOnlyT mark w) u t m ()
jot = toOverTT . jot
look
:: OverTT (AppendOnlyT mark w) u t m (mark w)
look = toOverTT look
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, Monoid w
, MonadTransTrans u, MonadIdentity mark, OverableT v
, forall x. (Monad x) => MonadAppendOnly mark w (u t x)
) => MonadAppendOnly mark w (OverTT v u t m)
where
jot
:: mark w
-> OverTT v u t m ()
jot = toOverTT . lift . jot
look
:: OverTT v u t m (mark w)
look = toOverTT $ lift look
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t
, MonadTransTrans u, MonadIdentity mark
) => MonadWriteOnce mark w (OverTT (WriteOnceT mark w) u t m)
where
etch
:: mark w
-> OverTT (WriteOnceT mark w) u t m Bool
etch = toOverTT . etch
press
:: OverTT (WriteOnceT mark w) u t m (Maybe (mark w))
press = toOverTT press
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadIdentity mark
, forall x. (Monad x) => MonadWriteOnce mark w (u t x)
) => MonadWriteOnce mark w (OverTT v u t m)
where
etch
:: mark w
-> OverTT v u t m Bool
etch = toOverTT . lift . etch
press
:: OverTT v u t m (Maybe (mark w))
press = toOverTT $ lift press
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t
, MonadTransTrans u, MonadIdentity mark
) => MonadHalt mark (OverTT (HaltT mark) u t m)
where
halt
:: mark ()
-> OverTT (HaltT mark) u t m a
halt = toOverTT . halt
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v
, MonadTransTrans u, MonadIdentity mark, OverableT v
, forall x. (Monad x) => MonadHalt mark (u t x)
) => MonadHalt mark (OverTT v u t m)
where
halt
:: mark ()
-> OverTT v u t m a
halt = toOverTT . lift . halt
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t
, MonadTransTrans u, MonadIdentity mark
) => MonadReadOnly mark r (OverTT (ReadOnlyT mark r) u t m)
where
ask
:: OverTT (ReadOnlyT mark r) u t m (mark r)
ask = toOverTT ask
local
:: (mark r -> mark r)
-> OverTT (ReadOnlyT mark r) u t m a
-> OverTT (ReadOnlyT mark r) u t m a
local f = toOverTT . local f . unOverTT
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadIdentity mark, LiftLocal v
, forall x. (Monad x) => MonadReadOnly mark r (u t x)
) => MonadReadOnly mark r (OverTT v u t m)
where
ask
:: OverTT v u t m (mark r)
ask = toOverTT $ lift ask
local
:: (mark r -> mark r)
-> OverTT v u t m a
-> OverTT v u t m a
local f = toOverTT . liftLocal local f . unOverTT
instance {-# OVERLAPS #-}
( Monad m, MonadTrans t
, MonadTransTrans u, MonadIdentity mark
) => MonadState mark s (OverTT (StateT mark s) u t m)
where
get
:: OverTT (StateT mark s) u t m (mark s)
get = toOverTT get
put
:: mark s
-> OverTT (StateT mark s) u t m ()
put = toOverTT . put
instance {-# OVERLAPPABLE #-}
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadIdentity mark
, forall x. (Monad x) => MonadState mark s (u t x)
) => MonadState mark s (OverTT v u t m)
where
get
:: OverTT v u t m (mark s)
get = toOverTT $ lift get
put
:: mark s
-> OverTT v u t m ()
put = toOverTT . lift . put
instance
( Monad m, MonadTrans t, MonadTrans v, OverableT v
, MonadTransTrans u, MonadPrompt mark p (u t m)
) => MonadPrompt mark p (OverTT v u t m)
where
prompt
:: mark (p a)
-> OverTT v u t m (mark a)
prompt = toOverTT . lift . prompt