-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Arrowized FRP implementation -- -- This library provides an arrowized functional reactive programming -- (FRP) implementation. It is similar to Yampa and Animas, but has a -- much simpler internal representation and a lot of new features. @package netwire @version 1.0.0 -- | The module contains the main Wire type. module FRP.NetWire.Wire -- | A wire is a network of signal transformers. data Wire a b WArr :: (a -> b) -> Wire a b WConst :: b -> Wire a b WGen :: (WireState -> a -> IO (Maybe b, Wire a b)) -> Wire a b WId :: Wire a a -- | The state of the wire. data WireState WireState :: Double -> MTGen -> TVar Int -> WireState -- | Time difference for current instant. wsDTime :: WireState -> Double -- | Random number generator. wsRndGen :: WireState -> MTGen -- | Request counter. wsReqVar :: WireState -> TVar Int -- | Derivative of time. In English: It's the time between two instants of -- an FRP session. type DTime = Double -- | Events are signals, which can be absent. They usually denote discrete -- occurences of certain events. type Event = Maybe -- | Time. type Time = Double -- | Clean up wire state. cleanupWireState :: WireState -> IO () -- | Initialize wire state. initWireState :: IO WireState -- | Create a generic wire from the given function. This is a smart -- constructor. Please use it instead of the WGen constructor. mkGen :: (WireState -> a -> IO (Maybe b, Wire a b)) -> Wire a b -- | Extract the transition function of a wire. toGen :: Wire a b -> WireState -> a -> IO (Maybe b, Wire a b) instance Functor (Wire a) instance Category Wire instance ArrowZero Wire instance ArrowPlus Wire instance ArrowChoice Wire instance Arrow Wire instance Applicative (Wire a) instance Alternative (Wire a) -- | Wire sessions. module FRP.NetWire.Session -- | Reactive sessions with the given time type. data Session a b Session :: TVar Bool -> IORef WireState -> IORef UTCTime -> IORef (Wire a b) -> Session a b -- | False, if in use. sessFreeVar :: Session a b -> TVar Bool -- | State of the last instant. sessStateRef :: Session a b -> IORef WireState -- | Time of the last instant. sessTimeRef :: Session a b -> IORef UTCTime -- | Wire for the next instant. sessWireRef :: Session a b -> IORef (Wire a b) -- | Feed the given input value into the reactive system performing the -- next instant using real time. stepWire :: a -> Session a b -> IO (Maybe b) -- | Feed the given input value into the reactive system performing the -- next instant using the given time delta. stepWireDelta :: NominalDiffTime -> a -> Session a b -> IO (Maybe b) -- | Feed the given input value into the reactive system performing the -- next instant, which is at the given time. This function is -- thread-safe. stepWireTime :: UTCTime -> a -> Session a b -> IO (Maybe b) -- | Feed the given input value into the reactive system performing the -- next instant, which is at the given time. This function is *not* -- thread-safe. stepWireTime' :: UTCTime -> a -> Session a b -> IO (Maybe b) -- | Initialize a reactive session and pass it to the given continuation. withWire :: Wire a b -> (Session a b -> IO c) -> IO c -- | The usual FRP tools you'll want to work with. module FRP.NetWire.Tools -- | The constant wire. Please use this function instead of arr (const -- c). constant :: b -> Wire a b -- | Identity signal transformer. Outputs its input. identity :: Wire a a -- | Get the local time. time :: Wire a Time -- | Get the local time, assuming it starts from the given value. timeFrom :: Time -> Wire a Time -- | Turn a continuous signal into a discrete one. This transformer picks -- values from the right signal at intervals of the left signal. -- -- The interval length is followed in real time. If it's zero, then this -- wire acts like second id. discrete :: Wire (DTime, a) a -- | Keep the value in the first instant forever. keep :: Wire a a -- | Unconditional inhibition. Equivalent to zeroArrow. inhibit :: Wire a b -- | Inhibit right signal, when the left signal is false. require :: Wire (Bool, a) a -- | This function corresponds to try for exceptions, allowing you -- to observe inhibited signals. exhibit :: Wire a b -> Wire a (Maybe b) -- | Effectively prevent a wire from rewiring itself. This function will -- turn any stateful wire into a stateless wire, rendering most wires -- useless. -- -- Note: This function should not be used normally. Use it only, if you -- know exactly what you're doing. freeze :: Wire a b -> Wire a b -- | Sample the given wire at specific intervals. Use this instead of -- discrete, if you want to prevent the signal from passing -- through the wire all the time. -- -- The left signal interval is allowed to become zero, at which point the -- signal is passed through the wire at every instant. sample :: Wire a b -> Wire (DTime, a) b -- | Wait for the first signal from the given wire and keep it forever. swallow :: Wire a b -> Wire a b -- | Override the output value at the first non-inhibited instant. (-->) :: b -> Wire a b -> Wire a b -- | Override the input value, until the wire starts producing. (>--) :: a -> Wire a b -> Wire a b -- | Apply a function to the wire's output at the first non-inhibited -- instant. (-=>) :: (b -> b) -> Wire a b -> Wire a b -- | Apply a function to the wire's input, until the wire starts producing. (>=-) :: (a -> a) -> Wire a b -> Wire a b -- | Produce the value of the second argument at the first instant. Then -- produce the second value forever. constantAfter :: b -> b -> Wire a b -- | Produce the argument value at the first instant. Then act as the -- identity signal transformer forever. initially :: a -> Wire a a -- | Apply an arrow to a list of inputs. mapA :: ArrowChoice a => a b c -> a [b] [c] -- | Duplicate a value to a tuple. dup :: a -> (a, a) -- | Floating point modulo operation. Note that fmod n 0 = 0. fmod :: Double -> Double -> Double -- | Swap the values in a tuple. swap :: (a, b) -> (b, a) -- | Switching combinators. Note that Wire also provides a -- state-preserving Control.Arrow.ArrowApply instance, which may -- be more convenient than these combinators in many cases. module FRP.NetWire.Switch -- | This is the most basic switching combinator. It is an event-based -- one-time switch. -- -- The first argument is the initial wire, which may produce a switching -- event at some point. When this event is produced, then the signal path -- switches to the wire produced by the second argument function. switch :: Wire a (b, Event c) -> (c -> Wire a b) -> Wire a b -- | Decoupled variant of switch. dSwitch :: Wire a (b, Event c) -> (c -> Wire a b) -> Wire a b -- | Combinator for recurrent switches. The wire produced by this switch -- takes switching events and switches to the wires contained in the -- events. The first argument is the initial wire. rSwitch :: Wire a b -> Wire (a, Event (Wire a b)) b -- | Decoupled variant of rSwitch. drSwitch :: Wire a b -> Wire (a, Event (Wire a b)) b -- | Broadcast signal to a collection of signal functions. If any of the -- wires inhibits, then the whole parallel network inhibits. parB :: Traversable f => f (Wire a b) -> Wire a (f b) -- | Recurrent parallel broadcast switch. This combinator acts like -- parB, but takes an additional event signal, which can transform -- the set of wires. -- -- Just like parB if any of the wires inhibits, the whole network -- inhibits. rpSwitchB :: Traversable f => f (Wire a b) -> Wire (a, Event (f (Wire a b) -> f (Wire a b))) (f b) -- | Decoupled variant of rpSwitchB. drpSwitchB :: Traversable f => f (Wire a b) -> Wire (a, Event (f (Wire a b) -> f (Wire a b))) (f b) -- | Route signal to a collection of signal functions using the supplied -- routing function. If any of the wires inhibits, the whole network -- inhibits. par :: Traversable f => (forall w. a -> f w -> f (b, w)) -> f (Wire b c) -> Wire a (f c) -- | Recurrent parallel routing switch. This combinator acts like -- par, but takes an additional event signal, which can transform -- the set of wires. This is the most powerful switch. -- -- Just like par if any of the wires inhibits, the whole network -- inhibits. rpSwitch :: Traversable f => (forall w. a -> f w -> f (b, w)) -> f (Wire b c) -> Wire (a, Event (f (Wire b c) -> f (Wire b c))) (f c) -- | Decoupled variant of rpSwitch. drpSwitch :: Traversable f => (forall w. a -> f w -> f (b, w)) -> f (Wire b c) -> Wire (a, Event (f (Wire b c) -> f (Wire b c))) (f c) -- | Unique identifiers. module FRP.NetWire.Request -- | Choose a unique identifier when switching in and keep it. identifier :: Wire a Int -- | Noise generators. module FRP.NetWire.Random -- | Noise between 0 (inclusive) and 1 (exclusive). noise :: Wire a Double -- | Noise between -1 and 1 exclusive. noise1 :: Wire a Double -- | Noise. noiseGen :: MTRandom b => Wire a b -- | Noise between 0 (inclusive) and the input signal (exclusive). noiseR :: (Real a, Integral b) => Wire a b -- | Random boolean. wackelkontakt :: Wire a Bool -- | Access the rest of the universe. module FRP.NetWire.IO -- | Execute the IO action in the input signal at every instant. -- -- Note: If the action throws an exception, then this wire inhibits the -- signal. execute :: Wire (IO a) a -- | Executes the IO action in the right input signal periodically keeping -- its most recent result value. executeEvery :: Wire (DTime, IO a) a -- | Executes the IO action in the input signal and inhibits, until it -- succeeds without an exception. Keeps the result forever. executeOnce :: Wire (IO a) a -- | Events. module FRP.NetWire.Event -- | Produce an event once after the specified delay and never again. The -- event's value will be the input signal at that point. after :: DTime -> Wire a (Event a) -- | Produce an event according to the given list of time deltas and event -- values. The time deltas are relative to each other, hence from the -- perspective of switching in [(1, a), (2, b), (3, -- c)] produces the event a after one -- second, b after three seconds and -- c after six seconds. afterEach :: [(DTime, b)] -> Wire a (Event b) -- | Produce a single event with the right signal whenever the left signal -- switches from False to True. edge :: Wire (Bool, a) (Event a) -- | Whenever the predicate in the first argument switches from -- False to True for the input signal, produce an event -- carrying the value given by applying the second argument function to -- the input signal. edgeBy :: (a -> Bool) -> (a -> b) -> Wire a (Event b) -- | Produce a single event carrying the value of the input signal, -- whenever the input signal switches to Just. edgeJust :: Wire (Maybe a) (Event a) -- | Never produce an event. never :: Wire a (Event b) -- | Produce an event at the first instant and never again. now :: b -> Wire a (Event b) -- | Pass the first event occurence through and suppress all future events. once :: Wire (Event a) (Event a) -- | Emit the right signal event each time the left signal interval passes. repeatedly :: Wire (DTime, a) (Event a) -- | Each time the signal interval passes emit the next element from the -- given list. repeatedlyList :: [a] -> Wire DTime (Event a) -- | Inhibit the signal, unless an event occurs. wait :: Wire (Event a) a -- | Event dam. Collects all values from the input list and emits one value -- at each instant. -- -- Note that this combinator can cause event congestion. If you feed -- values faster than it can produce, it will leak memory. dam :: Wire [a] (Event a) -- | Delay events by the time interval in the left signal. -- -- Note that this event transformer has to keep all delayed events in -- memory, which can cause event congestion. If events are fed in faster -- than they can be produced (for example when the framerate starts to -- drop), it will leak memory. Use delayEventSafe to prevent -- this. delayEvents :: Wire (DTime, Event a) (Event a) -- | Delay events by the time interval in the left signal. The event queue -- is limited to the maximum number of events given by middle signal. If -- the current queue grows to this size, then temporarily no further -- events are queued. -- -- As suggested by the type, this maximum can change over time. However, -- if it's decreased below the number of currently queued events, the -- events are not deleted. delayEventsSafe :: Wire (DTime, Int, Event a) (Event a) -- | Drop the given number of events, before passing events through. dropEvents :: Int -> Wire (Event a) (Event a) -- | Timed event gate for the right signal, which begins closed and opens -- after the time interval in the left signal has passed. dropFor :: Wire (DTime, Event a) (Event a) -- | Suppress the first event occurence. notYet :: Wire (Event a) (Event a) -- | Pass only the first given number of events. Then suppress events -- forever. takeEvents :: Int -> Wire (Event a) (Event a) -- | Timed event gate for the right signal, which starts open and slams -- shut after the left signal time interval passed. takeFor :: Wire (DTime, Event a) (Event a) -- | This function corresponds to the iterate function for lists. -- Begins with an initial output value, which is not emitted. Each time -- an input event is received, its function is applied to the current -- accumulator and the new value is emitted. accum :: a -> Wire (Event (a -> a)) (Event a) -- | Turn discrete events into continuous signals. Initially produces the -- argument value. Each time an event occurs, the produced value is -- switched to the event's value. hold :: a -> Wire (Event a) a -- | Decoupled variant of hold. dHold :: a -> Wire (Event a) a -- | Calculus functions. module FRP.NetWire.Calculus -- | Differentiate over time. Inhibits at first instant. derivative :: (NFData v, VectorSpace v, (Scalar v) ~ Double) => Wire v v -- | Differentiate over time. The argument is the value before the first -- instant. derivativeFrom :: (NFData v, VectorSpace v, (Scalar v) ~ Double) => v -> Wire v v -- | Integrate over time. The argument is the integration constant. integral :: (NFData v, VectorSpace v, (Scalar v) ~ Double) => v -> Wire v v -- | Signal analysis. module FRP.NetWire.Analyze -- | Emits an event, whenever the input signal changes. The event contains -- the last input value and the time elapsed since the last change. diff :: Eq a => Wire a (Event (a, Time)) -- | Calculate the average of the signal over the given number of last -- samples. This wire has O(n) space complexity and O(1) time complexity. -- -- If you need an average over all samples ever produced, consider using -- avgAll instead. avg :: (Fractional v, NFData v, Unbox v) => Int -> Wire v v -- | Calculate the average of the signal over all samples. -- -- Please note that somewhat surprisingly this wire runs in constant -- space and is generally faster than avg, but most applications -- will benefit from averages over only the last few samples. avgAll :: (Fractional v, NFData v) => Wire v v -- | Calculate the average number of frames per virtual second for the last -- given number of frames. -- -- Please note that this wire uses the clock, which you give the network -- using the stepping functions in FRP.NetWire.Session. If this -- clock doesn't represent real time, then the output of this wire won't -- either. avgFps :: Int -> Wire a Double -- | Returh the high peak. highPeak :: (NFData a, Ord a) => Wire a a -- | Return the low peak. lowPeak :: (NFData a, Ord a) => Wire a a -- | Return the high peak with the given comparison function. peakBy :: NFData a => (a -> a -> Ordering) -> Wire a a -- | Arrowized FRP implementation for networking applications. The aim of -- this library is to provide a convenient FRP implementation, which -- should enable you to write entirely pure network sessions. module FRP.NetWire -- | A wire is a network of signal transformers. data Wire a b -- | Time. type Time = Double -- | Derivative of time. In English: It's the time between two instants of -- an FRP session. type DTime = Double -- | Events are signals, which can be absent. They usually denote discrete -- occurences of certain events. type Event = Maybe -- | Reactive sessions with the given time type. data Session a b -- | Feed the given input value into the reactive system performing the -- next instant using real time. stepWire :: a -> Session a b -> IO (Maybe b) -- | Feed the given input value into the reactive system performing the -- next instant using the given time delta. stepWireDelta :: NominalDiffTime -> a -> Session a b -> IO (Maybe b) -- | Feed the given input value into the reactive system performing the -- next instant, which is at the given time. This function is -- thread-safe. stepWireTime :: UTCTime -> a -> Session a b -> IO (Maybe b) -- | Initialize a reactive session and pass it to the given continuation. withWire :: Wire a b -> (Session a b -> IO c) -> IO c