-- | Utility to define certain deterministic schedules.

module FRP.Rhine.Schedule.Util where

-- dunai
import Data.MonadicStreamFunction
import Data.MonadicStreamFunction.Async

-- | In a composite running clock,
--   duplicate the tick of one subclock.
duplicateSubtick :: Monad m => MSF m () (time, Either a b) -> MSF m () (time, Either a (Either a b))
duplicateSubtick :: MSF m () (time, Either a b)
-> MSF m () (time, Either a (Either a b))
duplicateSubtick MSF m () (time, Either a b)
runningClock = MStream m [(time, Either a (Either a b))]
-> MSF m () (time, Either a (Either a b))
forall (m :: Type -> Type) b.
Monad m =>
MStream m [b] -> MStream m b
concatS (MStream m [(time, Either a (Either a b))]
 -> MSF m () (time, Either a (Either a b)))
-> MStream m [(time, Either a (Either a b))]
-> MSF m () (time, Either a (Either a b))
forall a b. (a -> b) -> a -> b
$ MSF m () (time, Either a b)
runningClock MSF m () (time, Either a b)
-> MSF m (time, Either a b) [(time, Either a (Either a b))]
-> MStream m [(time, Either a (Either a b))]
forall k (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> ((time, Either a b) -> [(time, Either a (Either a b))])
-> MSF m (time, Either a b) [(time, Either a (Either a b))]
forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (time, Either a b) -> [(time, Either a (Either a b))]
forall a a b. (a, Either a b) -> [(a, Either a (Either a b))]
duplicateLeft
  where
    duplicateLeft :: (a, Either a b) -> [(a, Either a (Either a b))]
duplicateLeft (a
time, Left a
a)  = [(a
time, a -> Either a (Either a b)
forall a b. a -> Either a b
Left a
a), (a
time, Either a b -> Either a (Either a b)
forall a b. b -> Either a b
Right (Either a b -> Either a (Either a b))
-> Either a b -> Either a (Either a b)
forall a b. (a -> b) -> a -> b
$ a -> Either a b
forall a b. a -> Either a b
Left a
a)]
    duplicateLeft (a
time, Right b
b) = [(a
time, Either a b -> Either a (Either a b)
forall a b. b -> Either a b
Right (Either a b -> Either a (Either a b))
-> Either a b -> Either a (Either a b)
forall a b. (a -> b) -> a -> b
$ b -> Either a b
forall a b. b -> Either a b
Right b
b)]

-- TODO Why is stuff like this not in base? Maybe send pull request...
swapEither :: Either a b -> Either b a
swapEither :: Either a b -> Either b a
swapEither (Left  a
a) = a -> Either b a
forall a b. b -> Either a b
Right a
a
swapEither (Right b
b) = b -> Either b a
forall a b. a -> Either a b
Left  b
b