{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.Clock where
import Control.Arrow
import Control.Category qualified as Category
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Trans.Class (MonadTrans, lift)
import Data.Automaton (Automaton, arrM, hoistS)
import Data.TimeDomain
type RunningClock m time tag = Automaton m () (time, tag)
type RunningClockInit m time tag = m (RunningClock m time tag, time)
class (TimeDomain (Time cl)) => Clock m cl where
type Time cl
type Tag cl
initClock ::
cl ->
RunningClockInit m (Time cl) (Tag cl)
data TimeInfo cl = TimeInfo
{ forall cl. TimeInfo cl -> Diff (Time cl)
sinceLast :: Diff (Time cl)
, forall cl. TimeInfo cl -> Diff (Time cl)
sinceInit :: Diff (Time cl)
, forall cl. TimeInfo cl -> Time cl
absolute :: Time cl
, forall cl. TimeInfo cl -> Tag cl
tag :: Tag cl
}
retag ::
(Time cl1 ~ Time cl2) =>
(Tag cl1 -> Tag cl2) ->
TimeInfo cl1 ->
TimeInfo cl2
retag :: forall cl1 cl2.
(Time cl1 ~ Time cl2) =>
(Tag cl1 -> Tag cl2) -> TimeInfo cl1 -> TimeInfo cl2
retag Tag cl1 -> Tag cl2
f TimeInfo {Diff (Time cl1)
Time cl1
Tag cl1
sinceLast :: forall cl. TimeInfo cl -> Diff (Time cl)
sinceInit :: forall cl. TimeInfo cl -> Diff (Time cl)
absolute :: forall cl. TimeInfo cl -> Time cl
tag :: forall cl. TimeInfo cl -> Tag cl
sinceLast :: Diff (Time cl1)
sinceInit :: Diff (Time cl1)
absolute :: Time cl1
tag :: Tag cl1
..} = TimeInfo {tag :: Tag cl2
tag = Tag cl1 -> Tag cl2
f Tag cl1
tag, Diff (Time cl1)
Diff (Time cl2)
Time cl1
Time cl2
sinceLast :: Diff (Time cl2)
sinceInit :: Diff (Time cl2)
absolute :: Time cl2
sinceLast :: Diff (Time cl1)
sinceInit :: Diff (Time cl1)
absolute :: Time cl1
..}
type Rescaling cl time = Time cl -> time
type RescalingM m cl time = Time cl -> m time
type RescalingS m cl time tag = Automaton m (Time cl, Tag cl) (time, tag)
type RescalingSInit m cl time tag = Time cl -> m (RescalingS m cl time tag, time)
rescaleMToSInit ::
(Monad m) =>
(time1 -> m time2) ->
time1 ->
m (Automaton m (time1, tag) (time2, tag), time2)
rescaleMToSInit :: forall (m :: Type -> Type) time1 time2 tag.
Monad m =>
(time1 -> m time2)
-> time1 -> m (Automaton m (time1, tag) (time2, tag), time2)
rescaleMToSInit time1 -> m time2
rescaling time1
time1 = ((time1 -> m time2) -> Automaton m time1 time2
forall (m :: Type -> Type) a b.
Functor m =>
(a -> m b) -> Automaton m a b
arrM time1 -> m time2
rescaling Automaton m time1 time2
-> Automaton m tag tag -> Automaton m (time1, tag) (time2, tag)
forall b c b' c'.
Automaton m b c -> Automaton m b' c' -> Automaton m (b, b') (c, c')
forall (a :: Type -> Type -> Type) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** Automaton m tag tag
forall a. Automaton m a a
forall {k} (cat :: k -> k -> Type) (a :: k).
Category cat =>
cat a a
Category.id,) (time2 -> (Automaton m (time1, tag) (time2, tag), time2))
-> m time2 -> m (Automaton m (time1, tag) (time2, tag), time2)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> time1 -> m time2
rescaling time1
time1
data RescaledClock cl time = RescaledClock
{ forall cl time. RescaledClock cl time -> cl
unscaledClock :: cl
, forall cl time. RescaledClock cl time -> Rescaling cl time
rescale :: Rescaling cl time
}
instance
(Monad m, TimeDomain time, Clock m cl) =>
Clock m (RescaledClock cl time)
where
type Time (RescaledClock cl time) = time
type Tag (RescaledClock cl time) = Tag cl
initClock :: RescaledClock cl time
-> RunningClockInit
m (Time (RescaledClock cl time)) (Tag (RescaledClock cl time))
initClock (RescaledClock cl
cl Rescaling cl time
f) = do
(Automaton m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- cl -> m (Automaton m () (Time cl, Tag cl), Time cl)
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
cl
(Automaton m () (time, Tag cl), time)
-> m (Automaton m () (time, Tag cl), time)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( Automaton m () (Time cl, Tag cl)
runningClock Automaton m () (Time cl, Tag cl)
-> Automaton m (Time cl, Tag cl) (time, Tag cl)
-> Automaton m () (time, Tag cl)
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Automaton m (Time cl) time
-> Automaton m (Time cl, Tag cl) (time, Tag cl)
forall b c d. Automaton m b c -> Automaton m (b, d) (c, d)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (Rescaling cl time -> Automaton m (Time cl) time
forall b c. (b -> c) -> Automaton m b c
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr Rescaling cl time
f)
, Rescaling cl time
f Time cl
initTime
)
data RescaledClockM m cl time = RescaledClockM
{ forall (m :: Type -> Type) cl time. RescaledClockM m cl time -> cl
unscaledClockM :: cl
, forall (m :: Type -> Type) cl time.
RescaledClockM m cl time -> RescalingM m cl time
rescaleM :: RescalingM m cl time
}
instance
(Monad m, TimeDomain time, Clock m cl) =>
Clock m (RescaledClockM m cl time)
where
type Time (RescaledClockM m cl time) = time
type Tag (RescaledClockM m cl time) = Tag cl
initClock :: RescaledClockM m cl time
-> RunningClockInit
m
(Time (RescaledClockM m cl time))
(Tag (RescaledClockM m cl time))
initClock RescaledClockM {cl
RescalingM m cl time
unscaledClockM :: forall (m :: Type -> Type) cl time. RescaledClockM m cl time -> cl
rescaleM :: forall (m :: Type -> Type) cl time.
RescaledClockM m cl time -> RescalingM m cl time
unscaledClockM :: cl
rescaleM :: RescalingM m cl time
..} = do
(Automaton m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- cl -> m (Automaton m () (Time cl, Tag cl), Time cl)
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
unscaledClockM
time
rescaledInitTime <- RescalingM m cl time
rescaleM Time cl
initTime
(Automaton m () (time, Tag cl), time)
-> m (Automaton m () (time, Tag cl), time)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( Automaton m () (Time cl, Tag cl)
runningClock Automaton m () (Time cl, Tag cl)
-> Automaton m (Time cl, Tag cl) (time, Tag cl)
-> Automaton m () (time, Tag cl)
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Automaton m (Time cl) time
-> Automaton m (Time cl, Tag cl) (time, Tag cl)
forall b c d. Automaton m b c -> Automaton m (b, d) (c, d)
forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (RescalingM m cl time -> Automaton m (Time cl) time
forall (m :: Type -> Type) a b.
Functor m =>
(a -> m b) -> Automaton m a b
arrM RescalingM m cl time
rescaleM)
, time
rescaledInitTime
)
rescaledClockToM :: (Monad m) => RescaledClock cl time -> RescaledClockM m cl time
rescaledClockToM :: forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClock cl time -> RescaledClockM m cl time
rescaledClockToM RescaledClock {cl
Rescaling cl time
unscaledClock :: forall cl time. RescaledClock cl time -> cl
rescale :: forall cl time. RescaledClock cl time -> Rescaling cl time
unscaledClock :: cl
rescale :: Rescaling cl time
..} =
RescaledClockM
{ unscaledClockM :: cl
unscaledClockM = cl
unscaledClock
, rescaleM :: RescalingM m cl time
rescaleM = time -> m time
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return (time -> m time) -> Rescaling cl time -> RescalingM m cl time
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Rescaling cl time
rescale
}
data RescaledClockS m cl time tag = RescaledClockS
{ forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> cl
unscaledClockS :: cl
, forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> RescalingSInit m cl time tag
rescaleS :: RescalingSInit m cl time tag
}
instance
(Monad m, TimeDomain time, Clock m cl) =>
Clock m (RescaledClockS m cl time tag)
where
type Time (RescaledClockS m cl time tag) = time
type Tag (RescaledClockS m cl time tag) = tag
initClock :: RescaledClockS m cl time tag
-> RunningClockInit
m
(Time (RescaledClockS m cl time tag))
(Tag (RescaledClockS m cl time tag))
initClock RescaledClockS {cl
RescalingSInit m cl time tag
unscaledClockS :: forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> cl
rescaleS :: forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> RescalingSInit m cl time tag
unscaledClockS :: cl
rescaleS :: RescalingSInit m cl time tag
..} = do
(Automaton m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- cl -> m (Automaton m () (Time cl, Tag cl), Time cl)
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
unscaledClockS
(Automaton m (Time cl, Tag cl) (time, tag)
rescaling, time
rescaledInitTime) <- RescalingSInit m cl time tag
rescaleS Time cl
initTime
(Automaton m () (time, tag), time)
-> m (Automaton m () (time, tag), time)
forall a. a -> m a
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( Automaton m () (Time cl, Tag cl)
runningClock Automaton m () (Time cl, Tag cl)
-> Automaton m (Time cl, Tag cl) (time, tag)
-> Automaton m () (time, tag)
forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> Automaton m (Time cl, Tag cl) (time, tag)
rescaling
, time
rescaledInitTime
)
rescaledClockMToS ::
(Monad m) =>
RescaledClockM m cl time ->
RescaledClockS m cl time (Tag cl)
rescaledClockMToS :: forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClockM m cl time -> RescaledClockS m cl time (Tag cl)
rescaledClockMToS RescaledClockM {cl
RescalingM m cl time
unscaledClockM :: forall (m :: Type -> Type) cl time. RescaledClockM m cl time -> cl
rescaleM :: forall (m :: Type -> Type) cl time.
RescaledClockM m cl time -> RescalingM m cl time
unscaledClockM :: cl
rescaleM :: RescalingM m cl time
..} =
RescaledClockS
{ unscaledClockS :: cl
unscaledClockS = cl
unscaledClockM
, rescaleS :: RescalingSInit m cl time (Tag cl)
rescaleS = RescalingM m cl time -> RescalingSInit m cl time (Tag cl)
forall (m :: Type -> Type) time1 time2 tag.
Monad m =>
(time1 -> m time2)
-> time1 -> m (Automaton m (time1, tag) (time2, tag), time2)
rescaleMToSInit RescalingM m cl time
rescaleM
}
rescaledClockToS ::
(Monad m) =>
RescaledClock cl time ->
RescaledClockS m cl time (Tag cl)
rescaledClockToS :: forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClock cl time -> RescaledClockS m cl time (Tag cl)
rescaledClockToS = RescaledClockM m cl time -> RescaledClockS m cl time (Tag cl)
forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClockM m cl time -> RescaledClockS m cl time (Tag cl)
rescaledClockMToS (RescaledClockM m cl time -> RescaledClockS m cl time (Tag cl))
-> (RescaledClock cl time -> RescaledClockM m cl time)
-> RescaledClock cl time
-> RescaledClockS m cl time (Tag cl)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RescaledClock cl time -> RescaledClockM m cl time
forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClock cl time -> RescaledClockM m cl time
rescaledClockToM
data HoistClock m1 m2 cl = HoistClock
{ forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> cl
unhoistedClock :: cl
, forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> forall a. m1 a -> m2 a
monadMorphism :: forall a. m1 a -> m2 a
}
instance
(Monad m1, Monad m2, Clock m1 cl) =>
Clock m2 (HoistClock m1 m2 cl)
where
type Time (HoistClock m1 m2 cl) = Time cl
type Tag (HoistClock m1 m2 cl) = Tag cl
initClock :: HoistClock m1 m2 cl
-> RunningClockInit
m2 (Time (HoistClock m1 m2 cl)) (Tag (HoistClock m1 m2 cl))
initClock HoistClock {cl
forall a. m1 a -> m2 a
unhoistedClock :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> cl
monadMorphism :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> forall a. m1 a -> m2 a
unhoistedClock :: cl
monadMorphism :: forall a. m1 a -> m2 a
..} = do
(Automaton m1 () (Time cl, Tag cl)
runningClock, Time cl
initialTime) <- m1 (Automaton m1 () (Time cl, Tag cl), Time cl)
-> m2 (Automaton m1 () (Time cl, Tag cl), Time cl)
forall a. m1 a -> m2 a
monadMorphism (m1 (Automaton m1 () (Time cl, Tag cl), Time cl)
-> m2 (Automaton m1 () (Time cl, Tag cl), Time cl))
-> m1 (Automaton m1 () (Time cl, Tag cl), Time cl)
-> m2 (Automaton m1 () (Time cl, Tag cl), Time cl)
forall a b. (a -> b) -> a -> b
$ cl -> m1 (Automaton m1 () (Time cl, Tag cl), Time cl)
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
unhoistedClock
(Automaton m2 () (Time cl, Tag cl), Time cl)
-> m2 (Automaton m2 () (Time cl, Tag cl), Time cl)
forall a. a -> m2 a
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( (forall a. m1 a -> m2 a)
-> Automaton m1 () (Time cl, Tag cl)
-> Automaton m2 () (Time cl, Tag cl)
forall (m :: Type -> Type) (n :: Type -> Type) a b.
Monad m =>
(forall x. m x -> n x) -> Automaton m a b -> Automaton n a b
hoistS m1 x -> m2 x
forall a. m1 a -> m2 a
monadMorphism Automaton m1 () (Time cl, Tag cl)
runningClock
, Time cl
initialTime
)
type LiftClock m t cl = HoistClock m (t m) cl
liftClock :: (Monad m, MonadTrans t) => cl -> LiftClock m t cl
liftClock :: forall (m :: Type -> Type) (t :: (Type -> Type) -> Type -> Type)
cl.
(Monad m, MonadTrans t) =>
cl -> LiftClock m t cl
liftClock cl
unhoistedClock =
HoistClock
{ monadMorphism :: forall a. m a -> t m a
monadMorphism = m a -> t m a
forall a. m a -> t m a
forall (m :: Type -> Type) a. Monad m => m a -> t m a
forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift
, cl
unhoistedClock :: cl
unhoistedClock :: cl
..
}
type IOClock m cl = HoistClock IO m cl
ioClock :: (MonadIO m) => cl -> IOClock m cl
ioClock :: forall (m :: Type -> Type) cl. MonadIO m => cl -> IOClock m cl
ioClock cl
unhoistedClock =
HoistClock
{ monadMorphism :: forall a. IO a -> m a
monadMorphism = IO a -> m a
forall a. IO a -> m a
forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO
, cl
unhoistedClock :: cl
unhoistedClock :: cl
..
}