{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
module FRP.Rhine.Clock.Periodic (Periodic (Periodic)) where
import Data.List.NonEmpty hiding (unfold)
import Data.Maybe (fromMaybe)
import GHC.TypeLits (KnownNat, Nat, natVal)
import Data.MonadicStreamFunction
import Control.Monad.Schedule.Trans
import FRP.Rhine.Clock
import FRP.Rhine.Clock.Proxy
data Periodic (v :: [Nat]) where
Periodic :: Periodic (n : ns)
instance
(Monad m, NonemptyNatList v) =>
Clock (ScheduleT Integer m) (Periodic v)
where
type Time (Periodic v) = Integer
type Tag (Periodic v) = ()
initClock :: Periodic v
-> RunningClockInit
(ScheduleT Integer m) (Time (Periodic v)) (Tag (Periodic v))
initClock Periodic v
cl =
forall (m :: Type -> Type) a. Monad m => a -> m a
return
( forall (m :: Type -> Type) a. Monad m => NonEmpty a -> MSF m () a
cycleS (forall (v :: [Nat]).
NonemptyNatList v =>
Periodic v -> NonEmpty Integer
theList Periodic v
cl) forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> MSF m a a
withSideEffect forall (m :: Type -> Type) diff.
Monad m =>
diff -> ScheduleT diff m ()
wait forall {k} (cat :: k -> k -> Type) (a :: k) (b :: k) (c :: k).
Category cat =>
cat a b -> cat b c -> cat a c
>>> forall (m :: Type -> Type) a s.
Monad m =>
(a -> s -> s) -> s -> MSF m a s
accumulateWith forall a. Num a => a -> a -> a
(+) Integer
0 forall (a :: Type -> Type -> Type) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& forall (a :: Type -> Type -> Type) b c.
Arrow a =>
(b -> c) -> a b c
arr (forall a b. a -> b -> a
const ())
, Integer
0
)
instance GetClockProxy (Periodic v)
data HeadClProxy (n :: Nat) where
HeadClProxy :: Periodic (n : ns) -> HeadClProxy n
headCl :: (KnownNat n) => Periodic (n : ns) -> Integer
headCl :: forall (n :: Nat) (ns :: [Nat]).
KnownNat n =>
Periodic (n : ns) -> Integer
headCl Periodic (n : ns)
cl = forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal forall a b. (a -> b) -> a -> b
$ forall (n :: Nat) (n :: [Nat]). Periodic (n : n) -> HeadClProxy n
HeadClProxy Periodic (n : ns)
cl
tailCl :: Periodic (n1 : n2 : ns) -> Periodic (n2 : ns)
tailCl :: forall (n1 :: Nat) (n2 :: Nat) (ns :: [Nat]).
Periodic (n1 : n2 : ns) -> Periodic (n2 : ns)
tailCl Periodic (n1 : n2 : ns)
Periodic = forall (n :: Nat) (ns :: [Nat]). Periodic (n : ns)
Periodic
class NonemptyNatList (v :: [Nat]) where
theList :: Periodic v -> NonEmpty Integer
instance (KnownNat n) => NonemptyNatList '[n] where
theList :: Periodic '[n] -> NonEmpty Integer
theList Periodic '[n]
cl = forall (n :: Nat) (ns :: [Nat]).
KnownNat n =>
Periodic (n : ns) -> Integer
headCl Periodic '[n]
cl forall a. a -> [a] -> NonEmpty a
:| []
instance
(KnownNat n1, KnownNat n2, NonemptyNatList (n2 : ns)) =>
NonemptyNatList (n1 : n2 : ns)
where
theList :: Periodic (n1 : n2 : ns) -> NonEmpty Integer
theList Periodic (n1 : n2 : ns)
cl = forall (n :: Nat) (ns :: [Nat]).
KnownNat n =>
Periodic (n : ns) -> Integer
headCl Periodic (n1 : n2 : ns)
cl forall a. a -> NonEmpty a -> NonEmpty a
<| forall (v :: [Nat]).
NonemptyNatList v =>
Periodic v -> NonEmpty Integer
theList (forall (n1 :: Nat) (n2 :: Nat) (ns :: [Nat]).
Periodic (n1 : n2 : ns) -> Periodic (n2 : ns)
tailCl Periodic (n1 : n2 : ns)
cl)
cycleS :: (Monad m) => NonEmpty a -> MSF m () a
cycleS :: forall (m :: Type -> Type) a. Monad m => NonEmpty a -> MSF m () a
cycleS NonEmpty a
as = forall (m :: Type -> Type) a b.
Monad m =>
(a -> (b, a)) -> a -> MSF m () b
unfold (forall (a :: Type -> Type -> Type) b c d.
Arrow a =>
a b c -> a (d, b) (d, c)
second (forall a. a -> Maybe a -> a
fromMaybe NonEmpty a
as) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. NonEmpty a -> (a, Maybe (NonEmpty a))
uncons) NonEmpty a
as