h*p      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                 !!!!!!!"""""################################$$$%%%%%%%&&&&&&&&&&&'''(1.5+) Safe-Inferred'1 rhine Commute a  layer past an  layer.rhineCommute the effects of the  and the  monad.* Safe-Inferred'1 Mrhine Commute one  layer past a  layer. Safe-Inferred%&'1R xrhineLift a clock type into .yrhine+Lift a clock type into a monad transformer.zrhine-Applying a monad morphism yields a new clock.~rhineInstead of a mere function as morphism of time domains, we can transform one time domain into the other with an automaton.rhineThe clock before the rescalingrhineThe rescaling stream function, and rescaled initial time, depending on the initial time before rescalingrhineInstead of a mere function as morphism of time domains, we can transform one time domain into the other with an effectful morphism.rhineThe clock before the rescalingrhine4Computing the new time effectfully from the old timerhine7Applying a morphism of time domains yields a new clock.rhineLike , but allows for an initialisation of the rescaling morphism, together with the initial time.rhine6An effectful, stateful morphism of time domains is an  that uses side effects to rescale a point in one time domain into another one.rhineAn effectful morphism of time domains is a Kleisli arrow. It can use a side effect to rescale a point in one time domain into another one.rhine3A pure morphism of time domains is just a function.rhineAn annotated, rich time stamp.rhineTime passed since the last tickrhine1Time passed since the initialisation of the clockrhine%The absolute time of the current tickrhine&The tag annotation of the current tickrhineSince we want to leverage Haskell's type system to annotate signal networks by their clocks, each clock must be an own type, cl. Different values of the same clock type should tick at the same speed, and only differ in implementation details. Often, clocks are singletons.rhineThe time domain, i.e. type of the time stamps the clock creates.rhineAdditional information that the clock may output at each tick, e.g. if a realtime promise was met, if an event occurred, if one of its subclocks (if any) ticked.rhineThe method that produces to a clock value a running clock, i.e. an effectful stream of tagged time stamps together with an initialisation time.rhineWhen initialising a clock, the initial time is measured (typically by means of a side effect), and a running clock is returned.rhineA clock creates a stream of time stamps and additional information, possibly together with side effects in a monad m that cause the environment to wait until the specified time is reached.rhine$A utility that changes the tag of a .rhineConvert an effectful morphism of time domains into a stateful one with initialisation. Think of its type as 4RescalingM m cl time -> RescalingSInit m cl time tag%, although this type is ambiguous.rhineA  is trivially a .rhineA  is trivially a ~.rhineA  is trivially a ~.rhine,Lift a clock value into a monad transformer.rhineLift a clock value into .rhine>The clock value, containing e.g. settings or device parametersrhine/The stream of time stamps, and the initial time)xyz}|{~)~z}|{yx Safe-Inferred'1wrhine(Compatibility to U.S. american spelling.rhineA (side-effectful) behaviour function is a time-aware synchronous stream function that doesn't depend on a particular clock. time denotes the  TimeDomain.rhine(Compatibility to U.S. american spelling.rhineA (side-effectful) behaviour is a time-aware stream that doesn't depend on a particular clock. time denotes the  TimeDomain.rhineA clocked signal is a > with no input required. It produces its output on its own.rhineA (synchronous, clocked) automaton with the additional side effect of being time-aware, that is, reading the current  of the clock cl.rhineHoist a  along a monad morphism.rhineHoist a & and its clock along a monad morphism.rhineLift a  into a monad transformer.rhineLift a ( and its clock into a monad transformer.rhine0An automaton without dependency on time is a  for any clock.rhine+Utility to lift Kleisli arrows directly to s.rhineVersion without input.rhineCall a " every time the input is 'Just a'.Caution: This will not change the time differences since the last tick. For example, while  integrate 1 is approximately the same as timeInfoOf sinceInit, mapMaybe $ integrate 1 is very different from mapMaybe $ timeInfoOf sinceInit/. The former only integrates when the input is Just 1, whereas the latter always returns the correct time since initialisation.9LKM<=>?@CABDEFGHIJ;:NOPQRS!$ "#%&'()*+,-./ Safe-Inferred'1!rhine Commute two # transformer layers past each otherrhineCreate ("wrap") a < layer in the monad stack of a behaviour. Each tick, the  side effect is performed by passing the original behaviour the extra r input.rhineRemove ("run") a  layer from the monad stack by making it an explicit input to the behaviour.rhine Remove a 6 layer by passing the readonly environment explicitly. Safe-Inferred'1$rhine>Generates random values, updating the generator on every step.rhine: The monad that the signal function may take side effects ine,: The type of exceptions that can be thrownrhine)Immediately throw the incoming exception.rhine&Immediately throw the given exception.rhineDo not throw an exception.rhine#Throw the given exception when the  turns true.rhine Variant of *, where the exception can vary every tick.rhineThrow the exception e$ whenever the function evaluates to .rhine Variant of ? for Kleisli arrows. Throws the exception when the input is .rhineWhen the input is Just e, throw the exception e.rhine$Leave the monad context, to use the  as an 9.rhine0Enter the monad context in the exception for  s in the  monad. The . will be run until it encounters an exception.rhineWithin the same tick, perform a monadic action, and immediately throw the value as an exception.rhine A variant of  without input.rhineAdvances a single tick with the given Kleisli arrow, and then throws an exception.(Uuvw VWXYZpqrst763458763458 Safe-Inferred%&'1> rhine(Read the environment variable, i.e. the .rhine*Utility to apply functions to the current , such as record selectors:  printAbsoluteTime :: ClSF IO cl () () printAbsoluteTime = timeInfoOf absolute >>> arrMCl print rhine>> proc time -> do throwOn () - time* 1 returnA -< time safe sawtooth If you replace  by , it will usually hang after one second, since it doesn't reset after restarting the sawtooth.1Even in the absence of conditional activation of s, there is a difference: For a clock that doesn't tick at its initialisation time,  and  will have a constant offset of the duration between initialisation time and first tick.rhine Alias for +, (sequential composition) with higher operator precedence, designed to work with the other operators, e.g.: 1clsf1 >-> clsf2 @@ clA |@| clsf3 >-> clsf4 @@ clB&The type signature specialises e.g. to (>->) :: Monad m => ClSF m cl a b -> ClSF m cl b c -> ClSF m cl a crhine Alias for +-.rhineOutput a constant value. Specialises e.g. to this type signature: %arr_ :: Monad m => b -> ClSF m cl a brhine)The identity synchronous stream function.rhineThe output of integralFrom v0 is the numerical Euler integral of the input, with initial offset v0.rhine,Euler integration, with zero initial offset.rhineThe output of derivativeFrom v0 is the numerical derivative of the input, with a Newton difference quotient. The input is initialised with v0.rhine4Numerical derivative with input initialised to zero.rhineLike , but uses three samples to compute the derivative. Consequently, it is delayed by one sample.rhineLike 2, but with the initial position initialised to \.rhineA weighted moving average signal function. The output is the average of the first input, weighted by the second input (which is assumed to be always between 0 and 1). The weight is applied to the average of the last tick, so a weight of 1 simply repeats the past value unchanged, whereas a weight of 0 outputs the current value.rhineAn exponential moving average, or low pass. It will average out, or filter, all features below a given time constant t5. (Equivalently, it filters out frequencies above 1 / (2 * pi * t).)rhine-An average, or low pass, initialised to zero.rhineA linearised version of . It is more efficient, but only accurate if the supplied time scale is much bigger than the average time difference between two ticks.rhineLinearised version of .rhine Alias for .rhineFilters out frequencies below 1 / (2 * pi * t).rhine#Filters out frequencies other than 1 / (2 * pi * t).rhineFilters out the frequency 1 / (2 * pi * t).rhineRemembers and indefinitely outputs ("holds") the first input value.rhineRemembers all input values that arrived within a given time window. New values are appended left.rhineDelay a signal by certain time span, initialising with the first input.rhineThrows an exception after the specified time difference, outputting the time passed since the  was instantiated.rhineLike /, but doesn't output the remaining time at all.rhineLike 3, but divides the remaining time by the total time. rhineThe initial positionrhineThe initial positionrhineThe initial positionrhine.The time scale on which the signal is averagedrhine.The time scale on which the signal is averagedrhineThe initial positionrhine.The time scale on which the signal is averagedrhine.The time scale on which the signal is averagedrhineThe time constant trhineThe time constant trhineThe time constant trhineThe size of the time windowrhine!The time span to delay the signal  66. Safe-Inferred'1?z9LKM<=>?@CABDEFGHIJUuvw8!$ 367 "#%&'()*+,-./01245;:NOPQRSVWXYZpqrst  Safe-Inferred'1GrhineLike , but also output in the tag whether and by how much the target realtime was missed.The original clock specifies with its time stamps when, relative to the initialisation time, the UTC clock should tick. A tag of (tag, )" means that the tick was in time. (tag,  dt)% means that the tick was too late by dt.rhineA clock rescaled to the e time domain.There are different strategies how a clock may be rescaled, see below.rhine Rescale an : clock to the UTC time domain, overwriting its timestamps.rhine'Rescale a clock to the UTC time domain.The initial time stamp is measured as system time, and the increments (durations between ticks) are taken from the original clock. No attempt at waiting until the specified time is made, the timestamps of the original clock are trusted unconditionally.rhineMeasure the time after each tick, and wait for the remaining time until the next tick..If the next tick should already have occurred dt seconds ago, the tag is set to  dt*, representing a failed real time attempt.%Note that this clock internally uses  which can block for quite a lot longer than the requested time, which can cause  to miss one or more ticks when using a fast original clock. When using , 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 fast clocks it is recommended 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.  Safe-Inferred'1IrhineIf cl is a  in 'ScheduleT diff m', apply  to get a clock in m.rhine Remove a 5 layer from the monad transformer stack of the clock.The yield- action is interpreted as thread yielding in .  Safe-Inferred%&'1Lkrhine)A type synonym to allow for abbreviation.rhine%A stateful buffer from which one may  a value, or to which one may # a value, depending on the clocks. :s can be clock-polymorphic, or specific to certain clocks.m: Monad in which the  may have side effectscla+: The clock at which data enters the bufferclb+: The clock at which data leaves the buffera: The input typeb: The output typerhine!The internal state of the buffer.rhineStore one input value of type a7 at a given time stamp, and return an updated state.rhine"Retrieve one output value of type b0 at a given time stamp, and an updated state.rhineHoist a  along a monad morphism.2z{|}~yx  Safe-Inferred'1NrhineGiven a clocked signal function that accepts a varying number of timestamped inputs (a list), a  can be formed that collects all this input and steps the signal function whenever output is requested.rhineThe clocked signal function that consumes and a list of timestamped inputs, and outputs a single value. The list will contain the newest element in the head.  Safe-Inferred%&'1RorhineAn asynchronous, effectful Mealy machine description. (Input and output do not happen simultaneously.) It can be used to create s.rhineGiven the previous state and an input value, return the new state.rhineGiven the previous state, return an output value and a new state.rhineA resampling buffer that is unaware of the time information of the clock, and thus clock-polymorphic. It is built from an asynchronous Mealy machine description. Whenever  is called on "timelessResamplingBuffer machine s, the method  is called on machine with state s0, discarding the time stamp. Analogously for .rhine6A resampling buffer that only accepts and emits units.rhine=The asynchronous Mealy machine from which the buffer is builtrhineThe initial state Safe-Inferred%&'1TrhineAn unbounded LIFO buffer. If the buffer is empty, it will return .rhineA bounded LIFO buffer that forgets the oldest values when the size is above a given threshold. If the buffer is empty, it will return .rhine>-^ arr f , but  is slightly more efficient.rhineA buffer collecting all incoming values with a folding function. It is strict, i.e. the state value b is calculated on every .rhineThe folding functionrhineThe initial value Safe-Inferred'1[rhinePostcompose a  with a matching .rhine Precompose a  with a matching .rhineParallely compose two s.rhineParallely compose two s, duplicating the input.rhineGiven a  where the output type depends on the input type polymorphically, we can produce a timestamped version that simply annotates every input value with the  when it arrived.2144 Safe-Inferred%&'1`vrhineA simple linear interpolation based on the last calculated position and velocity.rhine7sinc-Interpolation, or Whittaker-Shannon-Interpolation.The incoming signal is strictly bandlimited by the frequency at which cl1 ticks. Each incoming value is hulled in a sinc function, these are added and sampled at cl2's ticks. In order not to produce a space leak, the buffer only remembers the past values within a given window, which should be chosen much larger than the average time between cl1 's ticks.rhine7Interpolates the signal with Hermite splines, using .Caution: In order to calculate the derivatives of the incoming signal, it has to be delayed by two ticks of cl1. In a non-realtime situation, a higher quality is achieved if the ticks of cl2 are delayed by two ticks of cl1.rhine/The initial velocity (derivative of the signal)rhineThe initial positionrhineThe size of the interpolation window (for how long in the past to remember incoming values)/ Safe-Inferred'1brhineA nonempty list of .s, unzipped into their states and their steps.rhineThe result of a stream, with the type arguments swapped, so it's usable with sop-corerhineOne step of a stream, with the state type argument going last, so it is usable with sop-core.rhineTransform an n-ary product of at least one type into a nonempty list of all its content.rhineRun $ concurrently by scheduling them in .rhine,Run a nonempty list of streams concurrently.  Safe-Inferred#%&')*1hR rhineAn inclusion of a clock into a tree of parallel compositions of clocks.rhineA tree representing possible last times to which the constituents of a clock may have ticked.rhineThe clock that represents the rate at which data leaves the system.rhineThe clock that represents the rate at which data enters the system.rhineAbbrevation synonym.rhineTwo clocks can be combined with a schedule as a clock for an asynchronous parallel composition of signal networks.rhineAbbrevation synonym.rhineTwo clocks can be combined with a schedule as a clock for an asynchronous sequential composition of signal networks.rhine"Run several automata concurrently.Whenever one automaton outputs a value, it is returned together with all other values that happen to be output at the same time.rhineRun two automata concurrently.7Whenever one automaton returns a value, it is returned.rhine$Run two running clocks concurrently.rhineA schedule implements a combination of two clocks. It outputs a time stamp and an  value, which specifies which of the two subclocks has ticked.rhineGenerates a tag for the composite clock from a tag of a leaf clock, given a parallel clock inclusion. Safe-Inferred')*1=jrhine"Extract a clock proxy from a type.rhineClocks should be able to automatically generate a proxy for themselves.rhineWitnesses the structure of a clock type, in particular whether s or s are involved.rhineReturn the incoming tag, assuming that the incoming clock is ticked, and  otherwise.rhineReturn the incoming tag, assuming that the outgoing clock is ticked, and  otherwise.   Safe-Inferred')*1prhineAn " is a side-effectful asynchronous signal network, where input, data processing (including side effects) and output need not happen at the same time.The type parameters are:m-: The monad in which side effects take place.cl: The clock of the whole signal network. It may be sequentially or parallely composed from other clocks.a,: The input type. Input arrives at the rate In cl.b.: The output type. Output arrives at the rate Out cl.rhineA synchronous automaton is the basic building block. For such an , data enters and leaves the system at the same rate as it is processed.rhineTwo 6s may be sequentially composed if there is a matching  between them.rhineTwo s with the same input and output data may be parallely composed.rhineBypass the signal network by forwarding data in parallel through a .rhineA $ can always be postcomposed onto an # if the clocks match on the output.rhineA # can always be precomposed onto an " if the clocks match on the input.rhine/Data can be looped back to the beginning of an (, but it must be resampled since the  and  clocks are generally different. Safe-Inferred')*1t/rhine2Postcompose a signal network with a pure function.rhine1Precompose a signal network with a pure function.rhine$Postcompose a signal network with a .rhine#Precompose a signal network with a .rhineCompose two signal networks on the same clock in data-parallel. At one tick of cl, both networks are stepped.rhineCompose two signal networks on different clocks in clock-parallel. At one tick of ParClock cl1 cl2, one of the networks is stepped, dependent on which constituent clock has ticked..Note: This is essentially an infix synonym of rhineCompose two signal networks on different clocks in clock-parallel. At one tick of ParClock cl1 cl2, one of the networks is stepped, dependent on which constituent clock has ticked. Safe-Inferred%&'1trhineGiven a clock value and an initial time, generate a stream of time stamps. Safe-Inferred')*1wrhineRun a clocked signal function as an automaton, accepting the timestamps and tags as explicit inputs.rhine%Run a signal network as an automaton.Depending on the incoming clock, input data may need to be provided, and depending on the outgoing clock, output data may be generated. There are thus possible invalid inputs, which  does not gracefully handle.rhine0Translate a resampling buffer into an automaton.The input decides whether the buffer is to accept input or has to produce output. (In the latter case, only time information is provided.) Safe-Inferred'1xrhine%A clock that always returns the tick (). Safe-Inferred%&'1zWrhine/A clock that selects certain subevents of type a", from the tag of a main clock.If two s would tick on the same type of subevents, but should not have the same type, one should newtype the subevent.rhineThe main clock | Return  if no tick of the subclock is required, or 'Just a' if the subclock should tick, with tag a.rhineHelper function that runs an  with $ output until it returns a value. Safe-Inferred'1{ rhineA clock that ticks for every line entered on the console, outputting the entered line as its . Safe-Inferred'1{rhineA clock that never ticks. Safe-Inferred'1 rhineA clock that ticks whenever an event is emitted. It is not yet bound to a specific channel, since ideally, the correct channel is created automatically by . If you want to create the channel manually and bind the clock to it, use .rhine:A monad transformer in which events can be emitted onto a .rhine Escape the  layer by explicitly providing a channel over which events are sent. Often this is not needed, and  can be used instead.rhineCreate a channel across which events can be communicated, and subsequently execute all event effects on this channel.)Ideally, this action is run _outside_ of flow, e.g. runEventChanT $ flow myRhine+. This way, exactly one channel is created.Caution: Don't use this with , since it would create a new channel every tick. Instead, create one chan :: Chan c , e.g. with T, and then use .rhineRemove ("run") an  layer from the monad stack by passing it explicitly the channel over which events are sent.-This is usually only needed if you can't use , to create the channel. Typically, create a chan :: Chan c1 in your main program before the main loop (e.g. flow) would be run, then, by using this function, pass the channel to every behaviour or * that wants to emit events, and, by using /, to every clock that should tick on the event.rhine'Emit a single event. This causes every ' on the same monad to tick immediately.=Be cautious when emitting events from a signal clocked by an . Nothing prevents you from emitting more events than are handled, causing the event buffer to grow indefinitely.rhineEmit an event on every tick.rhine*Emit an event whenever the input value is  Just event.rhineLike 8, but completely evaluates the event before emitting it.rhineLike 8, but completely evaluates the event before emitting it.rhineLike 8, but completely evaluates the event before emitting it.rhineCreate an event clock that is bound to a specific event channel. This is usually only useful if you can't apply  to the main loop (see ).TT Safe-Inferred'1rhineA clock that ticks without waiting. All time passed between ticks amounts to computation time, side effects, time measurement and framework overhead. Safe-Inferred'1rhineA rescaled version of  with  TimeDomain .rhineA side-effect free clock for audio synthesis and analysis. The sample rate is given by rate (of type ). Since this clock does not wait for the completion of buffers, the producer or the consumer of the signal has the obligation to synchronise the signal with the system clock, if realtime is desired. Otherwise, the clock is also suitable e.g. for batch processing of audio files.rhineA clock for audio analysis and synthesis. It internally processes samples in buffers of size  bufferSize, (the programmer does not have to worry about this), at a sample rate of rate (of type ). Both these parameters are in the type signature, so it is not possible to compose signals with different buffer sizes or sample rates.After processing a buffer, the clock will wait the remaining time until the next buffer must be processed, using system UTC time. The tag of the clock specifies whether the attempt to finish the last buffer in real time was successful. A value of  represents success, a value of  Just double represents a lag of double seconds.rhine3Rates at which audio signals are typically sampled.rhine Converts an ! to its corresponding rate as an .rhineA rescaled version of  with  TimeDomain  , using  to rescale.    Safe-Inferred')*01rhineA clock whose tick lengths cycle through a (nonempty) list of type-level natural numbers. E.g. Periodic '[1, 2]& ticks at times 1, 3, 4, 5, 7, 8, etc.&The waiting side effect is formal, in . You can use e.g.  to produce an actual delay.rhine8Repeatedly outputs the values of a given list, in order.! Safe-Inferred')*1rhine(A singleton clock that counts the ticks.rhineA pure (side effect free) clock with fixed step size, i.e. ticking at multiples of n. The tick rate is in the type signature, which prevents composition of signals at different rates.rhine4Extract the type-level natural number as an integer.rhineResample into a  clock that ticks n8 times slower, by collecting all values into a vector." Safe-Inferred'1rhineA clock ticking every n milliseconds, in real time.Since n is in the type signature, it is ensured that when composing two signals on a - clock, they will be driven at the same rate. For example,  1002 ticks every 0.1 seconds, so 10 times per seconds./The tag of this clock is 'Maybe Double', where % represents successful realtime, and  lag a lag (in seconds).rhine$Tries to achieve real time by using , see its docs.# Safe-Inferred'1krhine specialised to .rhine specialised to the monad  e2 .This is sometimes helpful when the type checker complains about an ambigous monad type variable.rhine specialised to .rhine Catch an  #, and throw it after one time step.rhineCatch an exception in clock cl" and throw it after one time step.This is particularly useful if you want to give your signal network a chance to save its current state in some way.rhine?A clock that emits a single tick, and then throws an exception.The tag, time measurement and exception have to be supplied as clock value.rhine)The tag that will be emitted on the tick.rhine%A method to measure the current time.rhine-The exception to throw after the single tick.rhine"A clock that throws no exceptions.rhine9Catch an exception in one clock and proceed with another.When cl1 throws an exception e (in  e7) while running, this exception is caught, and a clock cl2% is started from the exception value.For this to be possible, cl1 must run in the monad  e m, while cl2 must run in m . To give cl2 the ability to throw another exception, you need to add a further  layer to the stack in m.rhineHandle  exceptions purely in . The clock cl may throw  s of type e while running. These exceptions are automatically caught, and raised as an error in  (or more generally in  , which implies the presence of  in the monad transformer stack)'It can then be caught and handled with .rhine Combine two s under two different clocks.rhineRemove  from the monad of a clock, proving that no exception can be thrown.rhine Construct a  clock.rhineLike , but the exception thrown by cl and by the DelayException clock are the same.rhineBuild a 2. The time will be measured using the system time.rhine specialised to .rhineLike ., but throw the error without transforming it.rhine specialised to the monad  e2 .rhine., but throw the error without transforming it.rhine specialised to .rhine., but throw the error without transforming it.rhineExecuted until cl1 throws an exceptionrhineExecuted after cl1 threw an exception, when cl2 is startedrhine'The clock that will throw an exception erhineHow to transform the exception into the new exception that will be thrown laterrhineHow to measure the current time$ Safe-Inferred%&'1GrhineAn  can be given arbitrary other arguments that cause it to tick without doing anything and replicating the last output.rhine Upsample a # to a parallel clock. The given  is only called when clR ticks, otherwise the last output is replicated (with the given b as initialisation).rhine Upsample a # to a parallel clock. The given  is only called when clL ticks, otherwise the last output is replicated (with the given b as initialisation).% Safe-Inferred%&'1rhineA  consists of a ( together with a clock of matching type cl.It is a reactive program, possibly with open inputs and outputs. If the input and output types a and b are both (), that is, the  is "closed", then it is a standalone reactive program that can be run with the function flow.Otherwise, one can start the clock and the signal network jointly as an automaton, using .rhineStart the clock and the signal network, effectively hiding the clock type from the outside..Since the caller will not know when the clock  cl ticks, the input a? has to be given at all times, even those when it doesn't tick.rhine,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.& Safe-Inferred'1 rhineA purely syntactical convenience construction enabling quadruple syntax for sequential composition, as described below.rhineCreate a synchronous  by combining a clocked signal function with a matching clock. Synchronicity is ensured by requiring that data enters (In cl) and leaves (Out cl-) the system at the same as it is processed (cl).rhineSyntactic sugar for .rhineThe combinators for sequential composition allow for the following syntax: rh1 :: Rhine m cl1 a b rh1 = ... rh2 :: Rhine m cl2 c d rh2 = ... rb :: ResamplingBuffer m (Out cl1) (In cl2) b c rb = ... rh :: Rhine m (SequentialClock cl1 cl2) a d rh = rh1 >-- rb --> rh2 rhineThe combinators for parallel composition allow for the following syntax: rh1 :: Rhine m clL a b rh1 = ... rh2 :: Rhine m clR a c rh2 = ... rh :: Rhine m (ParallelClock clL clR) a (Either b c) rh = rh1 +@+ rh2 rhineThe combinators for parallel composition allow for the following syntax: rh1 :: Rhine m clL a b rh1 = ... rh2 :: Rhine m clR a b rh2 = ... rh :: Rhine m (ParallelClock clL clR) a b rh = rh1 |@| rh2 rhinePostcompose a  with a pure function.rhine Precompose a  with a pure function.rhinePostcompose a  with a .rhine Precompose a  with a .  52133' Safe-Inferred')*1rhineTakes a closed  (with trivial input and output), and runs it indefinitely. This is typically the main loop.All input has to be created, and all output has to be consumed by means of side effects in a monad m.Basic usage (synchronous case): sensor :: ClSF MyMonad MyClock () a sensor = constMCl produceData processing :: ClSF MyMonad MyClock a b processing = ... actuator :: ClSF MyMonad MyClock b () actuator = arrMCl consumeData mainSF :: ClSF MyMonad MyClock () () mainSF = sensor >-> processing >-> actuator main :: MyMonad () main = flow $ mainSF @@ clock rhineLike -, but with the type signature specialized to m ().;This is sometimes useful when dealing with ambiguous types.rhineRun a synchronous  with its clock as a main loop, similar to Yampa's, or Dunai's, . Safe-Inferred'1 9LKM<=>?@CABDEFGHIJU[\]^_`abcdefghikjlmnomz{|}~yxuvw8!$ 367 "#%&'()*+,-./01245;:NOPQRSTVWXYZpqrst 9LKM<=>?@CABDEFGHIJU[\]^_`abcdefghikjlmnomz{|}~yxuvw8!$ 367 "#%&'()*+,-./01245;:NOPQRSTVWXYZpqrst012013014015016078079:;<:;<:;=:;>?@A?@A?@B?@C?DE?DE?DF?DG?DH?DI?DJ?DK?DL?DM?DN?DO?DP?DQ?DR?DS?DT?DU?DV?DW?DX?DY?DZ?D[?D\?D]?D^?D_?D`?Da?Db?Dc?Dd?ef?eg?eh?ij?ik?il?im?in?io01p0+-0+,01q01r01r01s01t01u01v01w01x01y01z01{01|01|01}01~01010101010101010:;:;:;:;:;:;:;:;:;:;:;:;:;:;                                 !!!!!!!"""""################################$$$%%%%%%%&&&&&&&&&&&'''):)*?i00000/?////////////00000 00rhine-1.5-1yF8x0ye2B9vVCmk3Yh2O FRP.RhineFRP.Rhine.ClSF.RandomFRP.Rhine.ClSF.ExceptFRP.Rhine.Clock.Realtime.EventFRP.Rhine.ClockFRP.Rhine.ClSF.CoreFRP.Rhine.ClSF.ReaderFRP.Rhine.ClSF.UtilFRP.Rhine.Clock.RealtimeFRP.Rhine.Clock.UnscheduleFRP.Rhine.ResamplingBufferFRP.Rhine.ResamplingBuffer.ClSF#FRP.Rhine.ResamplingBuffer.TimelessFRP.Rhine.ResamplingBuffer.LIFO#FRP.Rhine.ResamplingBuffer.KeepLastFRP.Rhine.ResamplingBuffer.FIFO"FRP.Rhine.ResamplingBuffer.CollectFRP.Rhine.ResamplingBuffer.Util(FRP.Rhine.ResamplingBuffer.InterpolationFRP.Rhine.ScheduleFRP.Rhine.Clock.Proxy FRP.Rhine.SNFRP.Rhine.SN.CombinatorsFRP.Rhine.Clock.Util#FRP.Rhine.Reactimation.ClockErasureFRP.Rhine.Clock.TrivialFRP.Rhine.Clock.SelectFRP.Rhine.Clock.Realtime.StdinFRP.Rhine.Clock.Realtime.NeverFRP.Rhine.Clock.Realtime.BusyFRP.Rhine.Clock.Realtime.AudioFRP.Rhine.Clock.PeriodicFRP.Rhine.Clock.FixedStep$FRP.Rhine.Clock.Realtime.MillisecondFRP.Rhine.Clock.ExceptFRP.Rhine.ClSF.UpsampleFRP.Rhine.Type"FRP.Rhine.Reactimation.CombinatorsFRP.Rhine.ReactimationrhineFRP.Rhine.ClSF.Except.UtilFRP.Rhine.ClSF.Random.UtilControl.Category>>><<<FRP.Rhine.ClSFFRP.Rhine.Schedule.Internalbase Control.Arrowarrfirstapp|||loopControl.Monad.IO.ClassMonadIOliftIOtransformers-0.6.1.0Control.Monad.Trans.ExceptExceptT runExceptTthrowE$automaton-1.5-GiZNPJKjCKrL3EVGyCv3xUData.Stream.ResultResult resultStateoutputData.Automaton Automaton getAutomatonunfoldunfoldMunfold_arrMconstMhoistSliftSfeedback stepAutomaton reactimateembed withAutomaton mapMaybeS traverseS traverseS_ parallelyhandleAutomaton_handleAutomatonconcatSwithSideEffectaccumulateWith mappendFromdelayprependmappendSsumFromsumSsumNcountlastSData.Automaton.Trans.Random getRandomsS getRandomsRS getRandomsRS_Data.Automaton.Trans.ExceptexceptSrunAutomatonExcept currentInputsafelysafeforeverArrow ArrowLoop ArrowMonad ArrowApply ArrowChoiceleftright+++ ArrowPlus<+> ArrowZero zeroArrowKleisli runKleislisecond***&&&returnA^>>>>^<<^^<<leftAppControl.Concurrent.ChannewChanExcept runExcept mapExcept withExcept mapExceptT withExceptT0simple-affine-space-0.2.1-74ucbS7fm4g3wPtIMzWIo8Data.VectorSpace VectorSpace zeroVector*^^/^+^^-^ negateVectordotnorm normalize time-1.12.2 Data.Time.Clock.Internal.UTCTimeUTCTime*time-domain-0.1.0.5-5VXHMiQWV4r8kmODOTwOacData.TimeDomain NumTimeDomainfromNumTimeDomainTimeDifference differenceadd TimeDomainDiffdiffTimeaddTimeexceptcatchEhandleEtryEfinallyE liftCallCC liftListenliftPassIOClock LiftClock HoistClockunhoistedClock monadMorphismRescaledClockSunscaledClockSrescaleSRescaledClockMunscaledClockMrescaleM RescaledClock unscaledClockrescaleRescalingSInit RescalingS RescalingM RescalingTimeInfo sinceLast sinceInitabsolutetagClockTimeTag initClockRunningClockInit RunningClockretagrescaleMToSInitrescaledClockToMrescaledClockMToSrescaledClockToS liftClockioClock$fClockmRescaledClock$fClockmRescaledClockM$fClockmRescaledClockS$fClockm2HoistClock BehaviorF BehaviourFBehavior BehaviourClSignalClSF hoistClSFhoistClSFAndClockliftClSFliftClSFAndClocktimelessarrMClconstMClmapMaybecommuteReadersreaderS runReaderS runReaderS_runRandS evalRandS execRandS evalRandIOS evalRandIOS' getRandomS getRandomRS getRandomRS_BehaviorFExceptBehaviourFExcept ClSFExceptthrowSthrowpassthrowOnthrowOn' throwOnCond throwOnCondM throwMaybe runClSFExcepttryonceonce_steptimeInfo timeInfoOf sinceLastS sinceInitS absoluteStagS sinceStart>-><-<arr_clId integralFromintegralderivativeFrom derivativethreePointDerivativeFromthreePointDerivativeweightedAverageFrom averageFromaverageaverageLinFrom averageLinlowPasshighPassbandPassbandStop keepFirst historySincedelayBytimertimer_ scaledTimer WaitUTCClockUTCClock overwriteUTCaddUTCwaitUTCUnscheduleClock scheduleClock scheduleWait unyieldClock$fClockmUnscheduleClockResBufResamplingBufferbufferputgethoistResamplingBuffer$fFunctorResamplingBuffer$fProfunctorResamplingBuffer clsfBuffer AsyncMealyamPutamGettimelessResamplingBuffertrivialResamplingBuffer lifoUnbounded lifoBounded lifoWatchkeepLast fifoUnbounded fifoBounded fifoWatchcollectcollectSequence pureBuffer foldBuffer>>-^^->>*-*&-& timestampedlinearsinccubicParClockInclusion ParClockInL ParClockInR ParClockReflLastTimeSequentialLastTimeParallelLastTime LeafLastTimeOutInParClock ParallelClock parallelCl1 parallelCl2SeqClockSequentialClock sequentialCl1 sequentialCl2 scheduleList schedulePairrunningSchedule initScheduleparClockTagInclusion$fClockmSequentialClock$fClockmParallelClock ToClockProxyCl toClockProxy GetClockProxy getClockProxy ClockProxy LeafProxySequentialProxy ParallelProxyinProxyoutProxyinTagoutTag$fGetClockProxyRescaledClockS$fGetClockProxyRescaledClockM$fGetClockProxyRescaledClock$fGetClockProxyHoistClock$fGetClockProxyParallelClock$fGetClockProxySequentialClockSN Synchronous SequentialParallelFirstResampling Postcompose PrecomposeFeedback$fToClockProxySN>>>^^>>>>--^^-->****||||++++ genTimeInfoeraseClockClSF eraseClockSNeraseClockResBufTrivial$fGetClockProxyTrivial$fClockmTrivial SelectClock mainClockselectfilterS$fGetClockProxySelectClock$fClockmSelectClock$fMonoidSelectClock$fSemigroupSelectClock StdinClock$fSemigroupStdinClock$fGetClockProxyStdinClock$fClockmStdinClockNever$fGetClockProxyNever $fClockmNever EventClock EventChanTwithChan runEventChanT withChanSemitemitS emitSMaybeemit'emitS' emitSMaybe' eventClockOn$fGetClockProxyEventClock$fClockReaderTEventClock$fSemigroupEventClockBusy$fGetClockProxyBusy $fClockmBusyPureAudioClockFPureAudioClock AudioClock AudioRateHz44100Hz48000Hz96000pureAudioClockF$fGetClockProxyAudioClock$fClockmAudioClock$fAudioClockRateHz96000$fAudioClockRateHz48000$fAudioClockRateHz44100$fGetClockProxyPureAudioClock$fClockmPureAudioClockPeriodic$fGetClockProxyPeriodic$fNonemptyNatList:$fNonemptyNatList:0$fClockFreeTPeriodicCount FixedStepstepsizedownsampleFixedStep$fGetClockProxyFixedStep$fClockFreeTFixedStep Millisecond waitClock$fGetClockProxyMillisecond$fClockIOMillisecond DelayIOErrorDelayIOExceptionDelayMonadIOErrorDelayMonadIOExceptionDelayExceptionSingle singleTaggetTime exception SafeClock CatchClock ExceptClockgetExceptClock catchClSF safeClockdelayExceptiondelayException'delayMonadIOExceptiondelayMonadIOErrordelayMonadIOError'delayIOExceptiondelayIOException' delayIOError delayIOError'$fGetClockProxyExceptClock$fClockeioExceptClock$fGetClockProxyCatchClock$fClockmCatchClock$fClockmSingleupsampleAutomaton upsampleR upsampleLRhinesnclock eraseClock feedbackRhine$fToClockProxyRhineRhineAndResamplingBuffer@@>---->+@+|@|@>>^^>>@@>-^^->@flowflow_ reactimateClcommuteExceptReaderControl.Monad.Trans.ReaderReaderTcommuteReaderExceptcommuteReaderRand(MonadRandom-0.6.1-4LMEDbpvYu3C5TUhGoU5QkControl.Monad.Trans.Random.LazyRandTAutomatonExceptGHC.Basereturn>>=ghc-prim GHC.TypesBoolTrue GHC.MaybeNothingJustIO GHC.Conc.IO threadDelay-monad-schedule-0.2.0.1-CyDlsVLTG2x46kMz8kc7bkControl.Monad.Schedule.Trans ScheduleTStreams Data.StreamStreamT RunningResultStepapInjs_NPNonEmptyscheduleStreamsControl.Monad.Schedule.Class MonadSchedulescheduleStreams'stepsstatesgetRunningResultgetStep Data.EitherEitherMaybeChanFloatrateToIntegralGHC.RealIntegral GHC.Float double2Float runScheduleIOcycleSGHC.IO.ExceptionIOErrorGHC.Exception.Type Exception mtl-2.3.1Control.Monad.Error.Class MonadError