{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.Clock (
module FRP.Rhine.Clock,
module X,
)
where
import qualified Control.Category as Category
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Trans.Class (MonadTrans, lift)
import Data.MonadicStreamFunction as X hiding ((>>>^), (^>>>))
import Data.TimeDomain as X
type RunningClock m time tag = MSF 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
tag :: Tag cl1
absolute :: Time cl1
sinceInit :: Diff (Time cl1)
sinceLast :: Diff (Time cl1)
tag :: forall cl. TimeInfo cl -> Tag cl
absolute :: forall cl. TimeInfo cl -> Time cl
sinceInit :: forall cl. TimeInfo cl -> Diff (Time cl)
sinceLast :: forall cl. TimeInfo cl -> Diff (Time cl)
..} = TimeInfo {tag :: Tag cl2
tag = Tag cl1 -> Tag cl2
f Tag cl1
tag, Diff (Time cl1)
Time cl1
absolute :: Time cl1
sinceInit :: Diff (Time cl1)
sinceLast :: Diff (Time cl1)
absolute :: Time cl2
sinceInit :: Diff (Time cl2)
sinceLast :: Diff (Time cl2)
..}
type Rescaling cl time = Time cl -> time
type RescalingM m cl time = Time cl -> m time
type RescalingS m cl time tag = MSF 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 (MSF m (time1, tag) (time2, tag), time2)
rescaleMToSInit :: forall (m :: Type -> Type) time1 time2 tag.
Monad m =>
(time1 -> m time2)
-> time1 -> m (MSF m (time1, tag) (time2, tag), time2)
rescaleMToSInit time1 -> m time2
rescaling time1
time1 = (forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> MSF m a b
arrM time1 -> m time2
rescaling forall (a :: Type -> Type -> Type) b c b' c'.
Arrow a =>
a b c -> a b' c' -> a (b, b') (c, c')
*** forall {k} (cat :: k -> k -> Type) (a :: k).
Category cat =>
cat a a
Category.id,) 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
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
cl
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( MSF m () (Time cl, Tag cl)
runningClock forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (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
rescaleM :: RescalingM m cl time
unscaledClockM :: cl
rescaleM :: forall (m :: Type -> Type) cl time.
RescaledClockM m cl time -> RescalingM m cl time
unscaledClockM :: forall (m :: Type -> Type) cl time. RescaledClockM m cl time -> cl
..} = do
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- 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
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( MSF m () (Time cl, Tag cl)
runningClock forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (b, d) (c, d)
first (forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> MSF 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
rescale :: Rescaling cl time
unscaledClock :: cl
rescale :: forall cl time. RescaledClock cl time -> Rescaling cl time
unscaledClock :: forall cl time. RescaledClock cl time -> cl
..} =
RescaledClockM
{ unscaledClockM :: cl
unscaledClockM = cl
unscaledClock
, rescaleM :: RescalingM m cl time
rescaleM = forall (m :: Type -> Type) a. Monad m => a -> m a
return 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
rescaleS :: RescalingSInit m cl time tag
unscaledClockS :: cl
rescaleS :: forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> RescalingSInit m cl time tag
unscaledClockS :: forall (m :: Type -> Type) cl time tag.
RescaledClockS m cl time tag -> cl
..} = do
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initTime) <- forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
unscaledClockS
(MSF m (Time cl, Tag cl) (time, tag)
rescaling, time
rescaledInitTime) <- RescalingSInit m cl time tag
rescaleS Time cl
initTime
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( MSF m () (Time cl, Tag cl)
runningClock forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> MSF 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
rescaleM :: RescalingM m cl time
unscaledClockM :: cl
rescaleM :: forall (m :: Type -> Type) cl time.
RescaledClockM m cl time -> RescalingM m cl time
unscaledClockM :: forall (m :: Type -> Type) cl time. RescaledClockM m cl time -> cl
..} =
RescaledClockS
{ unscaledClockS :: cl
unscaledClockS = cl
unscaledClockM
, rescaleS :: RescalingSInit m cl time (Tag cl)
rescaleS = forall (m :: Type -> Type) time1 time2 tag.
Monad m =>
(time1 -> m time2)
-> time1 -> m (MSF 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 = forall (m :: Type -> Type) cl time.
Monad m =>
RescaledClockM m cl time -> RescaledClockS m cl time (Tag cl)
rescaledClockMToS forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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
monadMorphism :: forall a. m1 a -> m2 a
unhoistedClock :: cl
monadMorphism :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> forall a. m1 a -> m2 a
unhoistedClock :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) cl.
HoistClock m1 m2 cl -> cl
..} = do
(MSF m1 () (Time cl, Tag cl)
runningClock, Time cl
initialTime) <- forall a. m1 a -> m2 a
monadMorphism forall a b. (a -> b) -> a -> b
$ forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
unhoistedClock
let hoistMSF :: (forall a. m1 a -> m2 a) -> MSF m1 a b -> MSF m2 a b
hoistMSF = forall (m2 :: Type -> Type) (m1 :: Type -> Type) a b.
(Monad m2, Monad m1) =>
(forall c. m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b
morphS
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( forall {a} {b}.
(forall a. m1 a -> m2 a) -> MSF m1 a b -> MSF m2 a b
hoistMSF forall a. m1 a -> m2 a
monadMorphism MSF 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 = 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 = forall (m :: Type -> Type) a. MonadIO m => IO a -> m a
liftIO
, cl
unhoistedClock :: cl
unhoistedClock :: cl
..
}