rhine 0.8.0.1 → 0.8.1
raw patch · 13 files changed
+116/−26 lines, 13 filesdep ~basedep ~simple-affine-spacePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base, simple-affine-space
API changes (from Hackage documentation)
- FRP.Rhine.Clock.Periodic: instance (GHC.Base.Monad m, FRP.Rhine.Clock.Periodic.NonemptyNatList v) => FRP.Rhine.Clock.Clock (Control.Monad.Schedule.ScheduleT GHC.Integer.Type.Integer m) (FRP.Rhine.Clock.Periodic.Periodic v)
- FRP.Rhine.Clock.Proxy: type family Cl a :: Type;
+ FRP.Rhine: [Feedback] :: (Clock m (In cl), Clock m (Out cl), Time (In cl) ~ Time cl, Time (Out cl) ~ Time cl) => ResBuf m (Out cl) (In cl) d c -> SN m cl (a, c) (b, d) -> SN m cl a b
+ FRP.Rhine: [FirstResampling] :: (Clock m (In cl), Clock m (Out cl), Time cl ~ Time (Out cl), Time cl ~ Time (In cl)) => SN m cl a b -> ResamplingBuffer m (In cl) (Out cl) c d -> SN m cl (a, c) (b, d)
+ FRP.Rhine: add :: TimeDifference d => d -> d -> d
+ FRP.Rhine: addTime :: TimeDomain time => time -> Diff time -> time
+ FRP.Rhine: feedbackRhine :: (Clock m (In cl), Clock m (Out cl), Time (In cl) ~ Time cl, Time (Out cl) ~ Time cl) => ResamplingBuffer m (Out cl) (In cl) d c -> Rhine m cl (a, c) (b, d) -> Rhine m cl a b
+ FRP.Rhine: type Cl a :: Type;
+ FRP.Rhine: type Tag cl;
+ FRP.Rhine: type Time cl;
+ FRP.Rhine.ClSF.Core: add :: TimeDifference d => d -> d -> d
+ FRP.Rhine.ClSF.Core: addTime :: TimeDomain time => time -> Diff time -> time
+ FRP.Rhine.ClSF.Core: type Tag cl;
+ FRP.Rhine.ClSF.Core: type Time cl;
+ FRP.Rhine.Clock: add :: TimeDifference d => d -> d -> d
+ FRP.Rhine.Clock: addTime :: TimeDomain time => time -> Diff time -> time
+ FRP.Rhine.Clock: type Tag cl;
+ FRP.Rhine.Clock: type Time cl;
+ FRP.Rhine.Clock.Periodic: instance (GHC.Base.Monad m, FRP.Rhine.Clock.Periodic.NonemptyNatList v) => FRP.Rhine.Clock.Clock (Control.Monad.Schedule.ScheduleT GHC.Num.Integer.Integer m) (FRP.Rhine.Clock.Periodic.Periodic v)
+ FRP.Rhine.Clock.Proxy: type Cl a :: Type;
+ FRP.Rhine.SN: [Feedback] :: (Clock m (In cl), Clock m (Out cl), Time (In cl) ~ Time cl, Time (Out cl) ~ Time cl) => ResBuf m (Out cl) (In cl) d c -> SN m cl (a, c) (b, d) -> SN m cl a b
+ FRP.Rhine.SN: [FirstResampling] :: (Clock m (In cl), Clock m (Out cl), Time cl ~ Time (Out cl), Time cl ~ Time (In cl)) => SN m cl a b -> ResamplingBuffer m (In cl) (Out cl) c d -> SN m cl (a, c) (b, d)
+ FRP.Rhine.Type: feedbackRhine :: (Clock m (In cl), Clock m (Out cl), Time (In cl) ~ Time cl, Time (Out cl) ~ Time cl) => ResamplingBuffer m (Out cl) (In cl) d c -> Rhine m cl (a, c) (b, d) -> Rhine m cl a b
- FRP.Rhine: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ FRP.Rhine: (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
- FRP.Rhine: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ FRP.Rhine: (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
- FRP.Rhine: class Category a => Arrow (a :: Type -> Type -> Type)
+ FRP.Rhine: class Category a => Arrow (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: class Arrow a => ArrowApply (a :: Type -> Type -> Type)
+ FRP.Rhine: class Arrow a => ArrowApply (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: class Arrow a => ArrowChoice (a :: Type -> Type -> Type)
+ FRP.Rhine: class Arrow a => ArrowChoice (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: class Arrow a => ArrowLoop (a :: Type -> Type -> Type)
+ FRP.Rhine: class Arrow a => ArrowLoop (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type)
+ FRP.Rhine: class ArrowZero a => ArrowPlus (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: class Arrow a => ArrowZero (a :: Type -> Type -> Type)
+ FRP.Rhine: class Arrow a => ArrowZero (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine: type family Cl a :: Type;
+ FRP.Rhine: type family In cl
- FRP.Rhine.ClSF.Core: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ FRP.Rhine.ClSF.Core: (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
- FRP.Rhine.ClSF.Core: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ FRP.Rhine.ClSF.Core: (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
- FRP.Rhine.ClSF.Core: class Category a => Arrow (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class Category a => Arrow (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: class Arrow a => ArrowApply (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class Arrow a => ArrowApply (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: class Arrow a => ArrowChoice (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class Arrow a => ArrowChoice (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: class Arrow a => ArrowLoop (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class Arrow a => ArrowLoop (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class ArrowZero a => ArrowPlus (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: class Arrow a => ArrowZero (a :: Type -> Type -> Type)
+ FRP.Rhine.ClSF.Core: class Arrow a => ArrowZero (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.ClSF.Core: type family Tag cl;
+ FRP.Rhine.ClSF.Core: type family Diff time;
- FRP.Rhine.Clock: (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
+ FRP.Rhine.Clock: (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
- FRP.Rhine.Clock: (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
+ FRP.Rhine.Clock: (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
- FRP.Rhine.Clock: class Category a => Arrow (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class Category a => Arrow (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.Clock: class Arrow a => ArrowApply (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class Arrow a => ArrowApply (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.Clock: class Arrow a => ArrowChoice (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class Arrow a => ArrowChoice (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.Clock: class Arrow a => ArrowLoop (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class Arrow a => ArrowLoop (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.Clock: class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class ArrowZero a => ArrowPlus (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
- FRP.Rhine.Clock: class Arrow a => ArrowZero (a :: Type -> Type -> Type)
+ FRP.Rhine.Clock: class Arrow a => ArrowZero (a :: TYPE LiftedRep -> TYPE LiftedRep -> Type)
Files
- ChangeLog.md +5/−0
- rhine.cabal +7/−6
- src/FRP/Rhine/Clock.hs +0/−1
- src/FRP/Rhine/Clock/Periodic.hs +1/−3
- src/FRP/Rhine/Clock/Realtime/Audio.hs +0/−1
- src/FRP/Rhine/Clock/Realtime/Event.hs +2/−3
- src/FRP/Rhine/Clock/Realtime/Millisecond.hs +4/−6
- src/FRP/Rhine/Reactimation.hs +0/−2
- src/FRP/Rhine/Reactimation/ClockErasure.hs +34/−2
- src/FRP/Rhine/SN.hs +19/−0
- src/FRP/Rhine/SN/Combinators.hs +20/−1
- src/FRP/Rhine/Schedule.hs +1/−1
- src/FRP/Rhine/Type.hs +23/−0
ChangeLog.md view
@@ -4,6 +4,11 @@ Since `rhine` reexports modules from `dunai`, every major version in `dunai` triggers a major version in `rhine`. +## 0.8.1++* Support for GHC 9.2.4+* Added `FirstResampling` and `Feedback` constructors to `SN`+ ## 0.8.0.0 * Documentation improvements
rhine.cabal view
@@ -1,6 +1,6 @@ name: rhine -version: 0.8.0.1+version: 0.8.1 synopsis: Functional Reactive Programming with type-level clocks @@ -41,12 +41,12 @@ source-repository head type: git- location: git@github.com:turion/rhine.git+ location: https://github.com/turion/rhine.git source-repository this type: git- location: git@github.com:turion/rhine.git- tag: v0.8.0.1+ location: https://github.com/turion/rhine.git+ tag: v0.8.1 library@@ -99,7 +99,7 @@ -- other-extensions: -- Other library packages from which modules are imported.- build-depends: base >= 4.13 && < 4.16+ build-depends: base >= 4.13 && < 4.17 , dunai >= 0.8 , transformers >= 0.5 , time >= 1.8@@ -109,7 +109,8 @@ , deepseq >= 1.4 , random >= 1.1 , MonadRandom >= 0.5- , simple-affine-space+ -- Remove version pin when https://github.com/ivanperez-keera/dunai/issues/298 is resolved:+ , simple-affine-space == 0.1.1 , time-domain -- Directories containing source files.
src/FRP/Rhine/Clock.hs view
@@ -7,7 +7,6 @@ and certain general constructions of 'Clock's, such as clocks lifted along monad morphisms or time rescalings. -}-{-# LANGUAGE Arrows #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-}
src/FRP/Rhine/Clock/Periodic.hs view
@@ -8,12 +8,10 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE TypeSynonymInstances #-} module FRP.Rhine.Clock.Periodic (Periodic (Periodic)) where -- base@@ -45,7 +43,7 @@ type Time (Periodic v) = Integer type Tag (Periodic v) = () initClock cl = return- ( cycleS (theList cl) >>> withSideEffect wait >>> (accumulateWith (+) 0) &&& arr (const ())+ ( cycleS (theList cl) >>> withSideEffect wait >>> accumulateWith (+) 0 &&& arr (const ()) , 0 )
src/FRP/Rhine/Clock/Realtime/Audio.hs view
@@ -6,7 +6,6 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-}
src/FRP/Rhine/Clock/Realtime/Event.hs view
@@ -22,7 +22,6 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeFamilies #-}-{-# LANGUAGE TypeSynonymInstances #-} module FRP.Rhine.Clock.Realtime.Event ( module FRP.Rhine.Clock.Realtime.Event , module Control.Monad.IO.Class@@ -74,7 +73,7 @@ -} runEventChanT :: MonadIO m => EventChanT event m a -> m a runEventChanT a = do- chan <- liftIO $ newChan+ chan <- liftIO newChan runReaderT a chan {- | Remove ("run") an 'EventChanT' layer from the monad stack@@ -156,7 +155,7 @@ ( constM $ do chan <- ask event <- liftIO $ readChan chan- time <- liftIO $ getCurrentTime+ time <- liftIO getCurrentTime return (time, event) , initialTime )
src/FRP/Rhine/Clock/Realtime/Millisecond.hs view
@@ -2,9 +2,7 @@ Provides a clock that ticks at every multiple of a fixed number of milliseconds. -} -{-# LANGUAGE Arrows #-} {-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}@@ -56,12 +54,12 @@ -- Note that this clock internally uses 'threadDelay' which can block -- for quite a lot longer than the requested time, which can cause--- the clock to miss one or more ticks when using low values of 'n'. --- When using 'threadDelay', the difference between the real wait time --- and the requested wait time will be larger when using +-- the clock to miss one or more ticks when using low values of 'n'.+-- When using 'threadDelay', the difference between the real wait time+-- and the requested wait time will be larger when using -- the '-threaded' ghc option (around 800 microseconds) than when not using -- this option (around 100 microseconds). For low values of @n@ it is recommended--- that '-threaded' not be used in order to miss less ticks. The clock will adjust +-- that '-threaded' not be used in order to miss less ticks. The clock will adjust -- the wait time, up to no wait time at all, to catch up when a tick is missed. waitClock :: KnownNat n => Millisecond n
src/FRP/Rhine/Reactimation.hs view
@@ -3,9 +3,7 @@ as main loops. -} -{-# LANGUAGE Arrows #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE RecordWildCards #-} module FRP.Rhine.Reactimation where -- dunai
src/FRP/Rhine/Reactimation/ClockErasure.hs view
@@ -7,7 +7,6 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GADTs #-}-{-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TupleSections #-} module FRP.Rhine.Reactimation.ClockErasure where @@ -71,7 +70,7 @@ maybeB <- eraseClockSN initialTime sn1 -< (time, tagL, maybeA) returnA -< Left <$> ((time, , ) <$> outTag proxy1 tagL <*> maybeB) Right tagR -> do- returnA -< Right <$> (time, ) <$> inTag proxy2 tagR+ returnA -< Right . (time, ) <$> inTag proxy2 tagR maybeC <- mapMaybeS $ eraseClockResBuf (outProxy proxy1) (inProxy proxy2) initialTime resBuf -< resBufIn case tag of Left _ -> do@@ -97,6 +96,39 @@ in proc (time, tag, aMaybe) -> do bMaybe <- mapMaybeS $ eraseClockClSF (inProxy proxy) initialTime clsf -< (time, , ) <$> inTag proxy tag <*> aMaybe eraseClockSN initialTime sn -< (time, tag, bMaybe)++eraseClockSN initialTime (Feedback buf0 sn) =+ let+ proxy = toClockProxy sn+ in feedback buf0 $ proc ((time, tag, aMaybe), buf) -> do+ (cMaybe, buf') <- case inTag proxy tag of+ Nothing -> do+ returnA -< (Nothing, buf)+ Just tagIn -> do+ timeInfo <- genTimeInfo (inProxy proxy) initialTime -< (time, tagIn)+ (c, buf') <- arrM $ uncurry get -< (buf, timeInfo)+ returnA -< (Just c, buf')+ bdMaybe <- eraseClockSN initialTime sn -< (time, tag, (, ) <$> aMaybe <*> cMaybe)+ case (, ) <$> outTag proxy tag <*> bdMaybe of+ Nothing -> do+ returnA -< (Nothing, buf')+ Just (tagOut, (b, d)) -> do+ timeInfo <- genTimeInfo (outProxy proxy) initialTime -< (time, tagOut)+ buf'' <- arrM $ uncurry $ uncurry put -< ((buf', timeInfo), d)+ returnA -< (Just b, buf'')++eraseClockSN initialTime (FirstResampling sn buf) =+ let+ proxy = toClockProxy sn+ in proc (time, tag, acMaybe) -> do+ bMaybe <- eraseClockSN initialTime sn -< (time, tag, fst <$> acMaybe)+ let+ resBufInput = case (inTag proxy tag, outTag proxy tag, snd <$> acMaybe) of+ (Just tagIn, _, Just c) -> Just $ Left (time, tagIn, c)+ (_, Just tagOut, _) -> Just $ Right (time, tagOut)+ _ -> Nothing+ dMaybe <- mapMaybeS $ eraseClockResBuf (inProxy proxy) (outProxy proxy) initialTime buf -< resBufInput+ returnA -< (,) <$> bMaybe <*> join dMaybe -- | Translate a resampling buffer into a monadic stream function. --
src/FRP/Rhine/SN.hs view
@@ -69,6 +69,15 @@ => SN m cl1 a b -> SN m cl2 a b -> SN m (ParallelClock m cl1 cl2) a b+ -- | Bypass the signal network by forwarding data in parallel through a 'ResamplingBuffer'.+ FirstResampling+ :: ( Clock m (In cl), Clock m (Out cl)+ , Time cl ~ Time (Out cl)+ , Time cl ~ Time (In cl)+ )+ => SN m cl a b+ -> ResamplingBuffer m (In cl) (Out cl) c d+ -> SN m cl (a, c) (b, d) -- | A 'ClSF' can always be postcomposed onto an 'SN' if the clocks match on the output. Postcompose :: ( Clock m (Out cl)@@ -85,6 +94,16 @@ => ClSF m (In cl) a b -> SN m cl b c -> SN m cl a c+ -- | Data can be looped back to the beginning of an 'SN',+ -- but it must be resampled since the 'Out' and 'In' clocks are generally different.+ Feedback+ :: ( Clock m (In cl), Clock m (Out cl)+ , Time (In cl) ~ Time cl+ , Time (Out cl) ~ Time cl+ )+ => ResBuf m (Out cl) (In cl) d c+ -> SN m cl (a, c) (b, d)+ -> SN m cl a b instance GetClockProxy cl => ToClockProxy (SN m cl a b) where type Cl (SN m cl a b) = cl
src/FRP/Rhine/SN/Combinators.hs view
@@ -26,6 +26,8 @@ Parallel sn1 sn2 >>>^ f = Parallel (sn1 >>>^ f) (sn2 >>>^ f) Postcompose sn clsf >>>^ f = Postcompose sn $ clsf >>^ f Precompose clsf sn >>>^ f = Precompose clsf $ sn >>>^ f+Feedback buf sn >>>^ f = Feedback buf $ sn >>>^ first f+firstResampling@(FirstResampling _ _) >>>^ f = Postcompose firstResampling $ arr f -- | Precompose a signal network with a pure function. (^>>>)@@ -38,6 +40,8 @@ f ^>>> Parallel sn1 sn2 = Parallel (f ^>>> sn1) (f ^>>> sn2) f ^>>> Postcompose sn clsf = Postcompose (f ^>>> sn) clsf f ^>>> Precompose clsf sn = Precompose (f ^>> clsf) sn+f ^>>> Feedback buf sn = Feedback buf $ first f ^>>> sn+f ^>>> firstResampling@(FirstResampling _ _) = Precompose (arr f) firstResampling -- | Postcompose a signal network with a 'ClSF'. (>--^)@@ -74,9 +78,24 @@ rb = rb1 *-* rb2 Parallel sn11 sn12 **** Parallel sn21 sn22 = Parallel (sn11 **** sn21) (sn12 **** sn22)++Precompose clsf sn1 **** sn2 = Precompose (first clsf) $ sn1 **** sn2+sn1 **** Precompose clsf sn2 = Precompose (second clsf) $ sn1 **** sn2+Postcompose sn1 clsf **** sn2 = Postcompose (sn1 **** sn2) (first clsf)+sn1 **** Postcompose sn2 clsf = Postcompose (sn1 **** sn2) (second clsf)++Feedback buf sn1 **** sn2 = Feedback buf $ (\((a, c), c1) -> ((a, c1), c)) ^>>> (sn1 **** sn2) >>>^ (\((b, d1), d) -> ((b, d), d1))+sn1 **** Feedback buf sn2 = Feedback buf $ (\((a, c), c1) -> (a, (c, c1))) ^>>> (sn1 **** sn2) >>>^ (\(b, (d, d1)) -> ((b, d), d1))++FirstResampling sn1 buf **** sn2 = (\((a1, c1), c) -> ((a1, c), c1)) ^>>> FirstResampling (sn1 **** sn2) buf >>>^ (\((b1, d), d1) -> ((b1, d1), d))+sn1 **** FirstResampling sn2 buf = (\(a, (a1, c1)) -> ((a, a1), c1)) ^>>> FirstResampling (sn1 **** sn2) buf >>>^ (\((b, b1), d1) -> (b, (b1, d1)))+ -- Note that the patterns above are the only ones that can occur. -- This is ensured by the clock constraints in the SF constructors.-_ **** _ = error "Impossible pattern in ****"+Synchronous _ **** Parallel _ _ = error "Impossible pattern: Synchronous _ **** Parallel _ _"+Parallel _ _ **** Synchronous _ = error "Impossible pattern: Parallel _ _ **** Synchronous _"+Synchronous _ **** Sequential {} = error "Impossible pattern: Synchronous _ **** Sequential {}"+Sequential {} **** Synchronous _ = error "Impossible pattern: Sequential {} **** Synchronous _" -- | Compose two signal networks on different clocks in clock-parallel. -- At one tick of @ParClock m cl1 cl2@, one of the networks is stepped,
src/FRP/Rhine/Schedule.hs view
@@ -81,7 +81,7 @@ :: Monad m => Schedule m cl1 cl2 -> Schedule m (RescaledClock cl1 time) (RescaledClock cl2 time)-rescaledSchedule schedule = Schedule $ initSchedule'+rescaledSchedule schedule = Schedule initSchedule' where initSchedule' cl1 cl2 = initSchedule (rescaledScheduleS schedule) (rescaledClockToS cl1) (rescaledClockToS cl2)
src/FRP/Rhine/Type.hs view
@@ -6,6 +6,8 @@ {-# LANGUAGE Arrows #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE FlexibleContexts #-} module FRP.Rhine.Type where -- dunai@@ -16,6 +18,8 @@ import FRP.Rhine.Clock import FRP.Rhine.Clock.Proxy import FRP.Rhine.SN+import FRP.Rhine.ResamplingBuffer (ResamplingBuffer)+import FRP.Rhine.Schedule (Out, In) {- | A 'Rhine' consists of a 'SN' together with a clock of matching type 'cl'.@@ -55,3 +59,22 @@ return $ proc a -> do (time, tag) <- runningClock -< () eraseClockSN initTime sn -< (time, tag, a <$ inTag (toClockProxy sn) tag)++{- |+Loop back data from the output to the input.++Since output and input will generally tick at different clocks,+the data needs to be resampled.+-}+feedbackRhine+ :: ( Clock m (In cl), Clock m (Out cl)+ , Time (In cl) ~ Time cl+ , Time (Out cl) ~ Time cl+ )+ => ResamplingBuffer m (Out cl) (In cl) d c+ -> Rhine m cl (a, c) (b, d)+ -> Rhine m cl a b+feedbackRhine buf Rhine { .. } = Rhine+ { sn = Feedback buf sn+ , clock+ }