{-# LANGUAGE Arrows #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.Clock.Select where
import FRP.Rhine.Clock
import FRP.Rhine.Clock.Proxy
import FRP.Rhine.Schedule
import Data.MonadicStreamFunction.Async (concatS)
import Data.Maybe (catMaybes, maybeToList)
data SelectClock cl a = SelectClock
{ forall cl a. SelectClock cl a -> cl
mainClock :: cl
, forall cl a. SelectClock cl a -> Tag cl -> Maybe a
select :: Tag cl -> Maybe a
}
instance (Semigroup a, Semigroup cl) => Semigroup (SelectClock cl a) where
SelectClock cl a
cl1 <> :: SelectClock cl a -> SelectClock cl a -> SelectClock cl a
<> SelectClock cl a
cl2 =
SelectClock
{ mainClock :: cl
mainClock = forall cl a. SelectClock cl a -> cl
mainClock SelectClock cl a
cl1 forall a. Semigroup a => a -> a -> a
<> forall cl a. SelectClock cl a -> cl
mainClock SelectClock cl a
cl2
, select :: Tag cl -> Maybe a
select = \Tag cl
tag -> forall cl a. SelectClock cl a -> Tag cl -> Maybe a
select SelectClock cl a
cl1 Tag cl
tag forall a. Semigroup a => a -> a -> a
<> forall cl a. SelectClock cl a -> Tag cl -> Maybe a
select SelectClock cl a
cl2 Tag cl
tag
}
instance (Monoid cl, Semigroup a) => Monoid (SelectClock cl a) where
mempty :: SelectClock cl a
mempty =
SelectClock
{ mainClock :: cl
mainClock = forall a. Monoid a => a
mempty
, select :: Tag cl -> Maybe a
select = forall a b. a -> b -> a
const forall a. Monoid a => a
mempty
}
instance (Monad m, Clock m cl) => Clock m (SelectClock cl a) where
type Time (SelectClock cl a) = Time cl
type Tag (SelectClock cl a) = a
initClock :: SelectClock cl a
-> RunningClockInit
m (Time (SelectClock cl a)) (Tag (SelectClock cl a))
initClock SelectClock {cl
Tag cl -> Maybe a
select :: Tag cl -> Maybe a
mainClock :: cl
select :: forall cl a. SelectClock cl a -> Tag cl -> Maybe a
mainClock :: forall cl a. SelectClock cl a -> cl
..} = do
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initialTime) <- forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock cl
mainClock
let
runningSelectClock :: MSF m () (Time cl, a)
runningSelectClock = forall (m :: Type -> Type) b.
Monad m =>
MSF m () (Maybe b) -> MSF m () b
filterS forall a b. (a -> b) -> a -> b
$ proc ()
_ -> do
(Time cl
time, Tag cl
tag) <- MSF m () (Time cl, Tag cl)
runningClock -< ()
forall (a :: Type -> Type -> Type) b. Arrow a => a b b
returnA -< (Time cl
time,) forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Tag cl -> Maybe a
select Tag cl
tag
forall (m :: Type -> Type) a. Monad m => a -> m a
return (MSF m () (Time cl, a)
runningSelectClock, Time cl
initialTime)
instance GetClockProxy (SelectClock cl a)
schedSelectClocks ::
(Monad m, Semigroup cl, Clock m cl) =>
Schedule m (SelectClock cl a) (SelectClock cl b)
schedSelectClocks :: forall (m :: Type -> Type) cl a b.
(Monad m, Semigroup cl, Clock m cl) =>
Schedule m (SelectClock cl a) (SelectClock cl b)
schedSelectClocks = Schedule {forall {m :: Type -> Type} {cl} {a} {b}.
(Monad m, Clock m cl, Semigroup cl) =>
SelectClock cl a
-> SelectClock cl b -> m (MStream m (Time cl, Either a b), Time cl)
initSchedule :: SelectClock cl a
-> SelectClock cl b
-> RunningClockInit
m
(Time (SelectClock cl a))
(Either (Tag (SelectClock cl a)) (Tag (SelectClock cl b)))
initSchedule :: forall {m :: Type -> Type} {cl} {a} {b}.
(Monad m, Clock m cl, Semigroup cl) =>
SelectClock cl a
-> SelectClock cl b -> m (MStream m (Time cl, Either a b), Time cl)
..}
where
initSchedule :: SelectClock cl a
-> SelectClock cl b -> m (MStream m (Time cl, Either a b), Time cl)
initSchedule SelectClock cl a
subClock1 SelectClock cl b
subClock2 = do
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initialTime) <-
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock forall a b. (a -> b) -> a -> b
$
forall cl a. SelectClock cl a -> cl
mainClock SelectClock cl a
subClock1 forall a. Semigroup a => a -> a -> a
<> forall cl a. SelectClock cl a -> cl
mainClock SelectClock cl b
subClock2
let
runningSelectClocks :: MStream m (Time cl, Either a b)
runningSelectClocks = forall (m :: Type -> Type) b.
Monad m =>
MStream m [b] -> MStream m b
concatS forall a b. (a -> b) -> a -> b
$ proc ()
_ -> do
(Time cl
time, Tag cl
tag) <- MSF m () (Time cl, Tag cl)
runningClock -< ()
forall (a :: Type -> Type -> Type) b. Arrow a => a b b
returnA
-<
forall a. [Maybe a] -> [a]
catMaybes
[ (Time cl
time,) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. a -> Either a b
Left forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall cl a. SelectClock cl a -> Tag cl -> Maybe a
select SelectClock cl a
subClock1 Tag cl
tag
, (Time cl
time,) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> forall cl a. SelectClock cl a -> Tag cl -> Maybe a
select SelectClock cl b
subClock2 Tag cl
tag
]
forall (m :: Type -> Type) a. Monad m => a -> m a
return (MStream m (Time cl, Either a b)
runningSelectClocks, Time cl
initialTime)
schedSelectClockAndMain ::
(Monad m, Semigroup cl, Clock m cl) =>
Schedule m cl (SelectClock cl a)
schedSelectClockAndMain :: forall (m :: Type -> Type) cl a.
(Monad m, Semigroup cl, Clock m cl) =>
Schedule m cl (SelectClock cl a)
schedSelectClockAndMain = Schedule {forall {m :: Type -> Type} {cl} {b}.
(Monad m, Clock m cl, Semigroup cl) =>
cl
-> SelectClock cl b
-> m (MStream m (Time cl, Either (Tag cl) b), Time cl)
initSchedule :: forall {m :: Type -> Type} {cl} {b}.
(Monad m, Clock m cl, Semigroup cl) =>
cl
-> SelectClock cl b
-> m (MStream m (Time cl, Either (Tag cl) b), Time cl)
initSchedule :: cl
-> SelectClock cl a
-> RunningClockInit
m (Time cl) (Either (Tag cl) (Tag (SelectClock cl a)))
..}
where
initSchedule :: cl
-> SelectClock cl b
-> m (MStream m (Time cl, Either (Tag cl) b), Time cl)
initSchedule cl
mainClock' SelectClock {cl
Tag cl -> Maybe b
select :: Tag cl -> Maybe b
mainClock :: cl
select :: forall cl a. SelectClock cl a -> Tag cl -> Maybe a
mainClock :: forall cl a. SelectClock cl a -> cl
..} = do
(MSF m () (Time cl, Tag cl)
runningClock, Time cl
initialTime) <-
forall (m :: Type -> Type) cl.
Clock m cl =>
cl -> RunningClockInit m (Time cl) (Tag cl)
initClock forall a b. (a -> b) -> a -> b
$
cl
mainClock' forall a. Semigroup a => a -> a -> a
<> cl
mainClock
let
runningSelectClock :: MStream m (Time cl, Either (Tag cl) b)
runningSelectClock = forall (m :: Type -> Type) b.
Monad m =>
MStream m [b] -> MStream m b
concatS forall a b. (a -> b) -> a -> b
$ proc ()
_ -> do
(Time cl
time, Tag cl
tag) <- MSF m () (Time cl, Tag cl)
runningClock -< ()
forall (a :: Type -> Type -> Type) b. Arrow a => a b b
returnA
-<
forall a. [Maybe a] -> [a]
catMaybes
[ forall a. a -> Maybe a
Just (Time cl
time, forall a b. a -> Either a b
Left Tag cl
tag)
, (Time cl
time,) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Tag cl -> Maybe b
select Tag cl
tag
]
forall (m :: Type -> Type) a. Monad m => a -> m a
return (MStream m (Time cl, Either (Tag cl) b)
runningSelectClock, Time cl
initialTime)
filterS :: Monad m => MSF m () (Maybe b) -> MSF m () b
filterS :: forall (m :: Type -> Type) b.
Monad m =>
MSF m () (Maybe b) -> MSF m () b
filterS = forall (m :: Type -> Type) b.
Monad m =>
MStream m [b] -> MStream m b
concatS forall b c a. (b -> c) -> (a -> b) -> a -> c
. (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.
Arrow a =>
(b -> c) -> a b c
arr forall a. Maybe a -> [a]
maybeToList)