module Simulation.Aivika.Channel
(
Channel(..),
delayChannel,
delayChannelM,
sinkSignal,
traceChannel) where
import qualified Control.Category as C
import Control.Monad
import Simulation.Aivika.Simulation
import Simulation.Aivika.Dynamics
import Simulation.Aivika.Event
import Simulation.Aivika.Signal
import Simulation.Aivika.Composite
newtype Channel a b =
Channel { Channel a b -> Signal a -> Composite (Signal b)
runChannel :: Signal a -> Composite (Signal b)
}
instance C.Category Channel where
id :: Channel a a
id = (Signal a -> Composite (Signal a)) -> Channel a a
forall a b. (Signal a -> Composite (Signal b)) -> Channel a b
Channel Signal a -> Composite (Signal a)
forall (m :: * -> *) a. Monad m => a -> m a
return
(Channel Signal b -> Composite (Signal c)
g) . :: Channel b c -> Channel a b -> Channel a c
. (Channel Signal a -> Composite (Signal b)
f) =
(Signal a -> Composite (Signal c)) -> Channel a c
forall a b. (Signal a -> Composite (Signal b)) -> Channel a b
Channel ((Signal a -> Composite (Signal c)) -> Channel a c)
-> (Signal a -> Composite (Signal c)) -> Channel a c
forall a b. (a -> b) -> a -> b
$ \Signal a
a -> Signal a -> Composite (Signal b)
f Signal a
a Composite (Signal b)
-> (Signal b -> Composite (Signal c)) -> Composite (Signal c)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Signal b -> Composite (Signal c)
g
delayChannel :: Double
-> Channel a a
delayChannel :: Double -> Channel a a
delayChannel Double
delay =
(Signal a -> Composite (Signal a)) -> Channel a a
forall a b. (Signal a -> Composite (Signal b)) -> Channel a b
Channel ((Signal a -> Composite (Signal a)) -> Channel a a)
-> (Signal a -> Composite (Signal a)) -> Channel a a
forall a b. (a -> b) -> a -> b
$ \Signal a
a -> Signal a -> Composite (Signal a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Signal a -> Composite (Signal a))
-> Signal a -> Composite (Signal a)
forall a b. (a -> b) -> a -> b
$ Double -> Signal a -> Signal a
forall a. Double -> Signal a -> Signal a
delaySignal Double
delay Signal a
a
delayChannelM :: Event Double
-> Channel a a
delayChannelM :: Event Double -> Channel a a
delayChannelM Event Double
delay =
(Signal a -> Composite (Signal a)) -> Channel a a
forall a b. (Signal a -> Composite (Signal b)) -> Channel a b
Channel ((Signal a -> Composite (Signal a)) -> Channel a a)
-> (Signal a -> Composite (Signal a)) -> Channel a a
forall a b. (a -> b) -> a -> b
$ \Signal a
a -> Signal a -> Composite (Signal a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Signal a -> Composite (Signal a))
-> Signal a -> Composite (Signal a)
forall a b. (a -> b) -> a -> b
$ Event Double -> Signal a -> Signal a
forall a. Event Double -> Signal a -> Signal a
delaySignalM Event Double
delay Signal a
a
sinkSignal :: Signal a -> Composite ()
sinkSignal :: Signal a -> Composite ()
sinkSignal Signal a
a =
do DisposableEvent
h <- Event DisposableEvent -> Composite DisposableEvent
forall (m :: * -> *) a. EventLift m => Event a -> m a
liftEvent (Event DisposableEvent -> Composite DisposableEvent)
-> Event DisposableEvent -> Composite DisposableEvent
forall a b. (a -> b) -> a -> b
$
Signal a -> (a -> Event ()) -> Event DisposableEvent
forall a. Signal a -> (a -> Event ()) -> Event DisposableEvent
handleSignal Signal a
a ((a -> Event ()) -> Event DisposableEvent)
-> (a -> Event ()) -> Event DisposableEvent
forall a b. (a -> b) -> a -> b
$
Event () -> a -> Event ()
forall a b. a -> b -> a
const (Event () -> a -> Event ()) -> Event () -> a -> Event ()
forall a b. (a -> b) -> a -> b
$ () -> Event ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
DisposableEvent -> Composite ()
disposableComposite DisposableEvent
h
traceChannel :: String -> Channel a b -> Channel a b
traceChannel :: String -> Channel a b -> Channel a b
traceChannel String
message (Channel Signal a -> Composite (Signal b)
f) =
(Signal a -> Composite (Signal b)) -> Channel a b
forall a b. (Signal a -> Composite (Signal b)) -> Channel a b
Channel ((Signal a -> Composite (Signal b)) -> Channel a b)
-> (Signal a -> Composite (Signal b)) -> Channel a b
forall a b. (a -> b) -> a -> b
$ \Signal a
a ->
do Signal b
b <- Signal a -> Composite (Signal b)
f Signal a
a
Signal b -> Composite (Signal b)
forall (m :: * -> *) a. Monad m => a -> m a
return (Signal b -> Composite (Signal b))
-> Signal b -> Composite (Signal b)
forall a b. (a -> b) -> a -> b
$
String -> Signal b -> Signal b
forall a. String -> Signal a -> Signal a
traceSignal String
message Signal b
b