module Simulation.Aivika.Trans.Composite
(
Composite,
CompositeLift(..),
runComposite,
runComposite_,
runCompositeInStartTime_,
runCompositeInStopTime_,
disposableComposite) where
import Data.Monoid
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Fix
import Control.Applicative
import Simulation.Aivika.Trans.Comp
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Parameter
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Dynamics
import Simulation.Aivika.Trans.Event
newtype Composite m a = Composite { runComposite :: DisposableEvent m -> Event m (a, DisposableEvent m)
}
runComposite_ :: Monad m => Composite m a -> Event m a
runComposite_ m =
do (a, _) <- runComposite m mempty
return a
runCompositeInStartTime_ :: MonadDES m => Composite m a -> Simulation m a
runCompositeInStartTime_ = runEventInStartTime . runComposite_
runCompositeInStopTime_ :: MonadDES m => Composite m a -> Simulation m a
runCompositeInStopTime_ = runEventInStopTime . runComposite_
disposableComposite :: Monad m => DisposableEvent m -> Composite m ()
disposableComposite h = Composite $ \h0 -> return ((), h0 <> h)
instance Monad m => Functor (Composite m) where
fmap f (Composite m) =
Composite $ \h0 ->
do (a, h) <- m h0
return (f a, h)
instance Monad m => Applicative (Composite m) where
pure = return
(<*>) = ap
instance Monad m => Monad (Composite m) where
return a = Composite $ \h0 -> return (a, h0)
(Composite m) >>= k =
Composite $ \h0 ->
do (a, h) <- m h0
let Composite m' = k a
(b, h') <- m' h
return (b, h')
instance (Monad m, MonadIO (Event m)) => MonadIO (Composite m) where
liftIO m =
Composite $ \h0 ->
do a <- liftIO m
return (a, h0)
instance (Monad m, MonadFix (Event m)) => MonadFix (Composite m) where
mfix f =
Composite $ \h0 ->
do rec (a, h) <- runComposite (f a) h0
return (a, h)
instance MonadTrans Composite where
lift m =
Composite $ \h0 ->
do a <- lift m
return (a, h0)
instance Monad m => MonadCompTrans Composite m where
liftComp m =
Composite $ \h0 ->
do a <- liftComp m
return (a, h0)
instance Monad m => ParameterLift Composite m where
liftParameter m =
Composite $ \h0 ->
do a <- liftParameter m
return (a, h0)
instance Monad m => SimulationLift Composite m where
liftSimulation m =
Composite $ \h0 ->
do a <- liftSimulation m
return (a, h0)
instance Monad m => DynamicsLift Composite m where
liftDynamics m =
Composite $ \h0 ->
do a <- liftDynamics m
return (a, h0)
instance Monad m => EventLift Composite m where
liftEvent m =
Composite $ \h0 ->
do a <- liftEvent m
return (a, h0)
class CompositeLift t m where
liftComposite :: Composite m a -> t m a
instance Monad m => CompositeLift Composite m where
liftComposite = id