-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | FRP Yampa replacement implemented with Monadic Stream Functions. -- -- Yampa is a popular Functional Reactive Programming (FRP) -- implementation that has been used extensively for all kinds of -- applications, including robotics and games. -- -- Monadic Stream Functions are a new abstraction for data -- processors that combine arrows and monads. The library dunai -- provides a default implementation. -- -- Bearriver (a tributary to the Yampa river) provides the same API as -- Yampa, but implemented using dunai underneath. The goal is to -- facilitate understanding what's different about Yampa, and other FRP -- and Reactive Programming libraries, by creating wrappers around dunai -- defined precisely by those differences. -- -- Because dunai is particularly fast, especially with optimizations -- enabled, this implementation is faster than traditional Yampa for -- medium-sized and large applications. @package bearriver @version 0.13.6 module FRP.BearRiver -- | A value that may or may not exist. -- -- Used to represent discrete-time signals. data Event a Event :: a -> Event a NoEvent :: Event a -- | Information on the progress of time. type ClockInfo m = ReaderT DTime m -- | Extensible signal function (signal function with a notion of time, but -- which can be extended with actions). type SF m = MSF (ClockInfo m) -- | Time deltas or increments (conceptually positive). type DTime = Double -- | Absolute time. type Time = Double arrPrim :: Monad m => (a -> b) -> SF m a b arrEPrim :: Monad m => (Event a -> b) -> SF m (Event a) b identity :: Monad m => SF m a a constant :: Monad m => b -> SF m a b localTime :: Monad m => SF m a Time time :: Monad m => SF m a Time -- | Initialization operator (cf. Lustre/Lucid Synchrone). -- -- The output at time zero is the first argument, and from that point on -- it behaves like the signal function passed as second argument. (-->) :: Monad m => b -> SF m a b -> SF m a b infixr 0 --> -- | Output pre-insert operator. -- -- Insert a sample in the output, and from that point on, behave like the -- given sf. (-:>) :: Monad m => b -> SF m a b -> SF m a b infixr 0 -:> -- | Input initialization operator. -- -- The input at time zero is the first argument, and from that point on -- it behaves like the signal function passed as second argument. (>--) :: Monad m => a -> SF m a b -> SF m a b infixr 0 >-- (>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b infixr 0 >=- initially :: Monad m => a -> SF m a a sscan :: Monad m => (b -> a -> b) -> b -> SF m a b sscanPrim :: Monad m => (c -> a -> Maybe (c, b)) -> c -> b -> SF m a b -- | Event source that never occurs. never :: Monad m => SF m a (Event b) -- | Event source with a single occurrence at time 0. The value of the -- event is given by the function argument. now :: Monad m => b -> SF m a (Event b) after :: Monad m => Time -> b -> SF m a (Event b) repeatedly :: Monad m => Time -> b -> SF m a (Event b) -- | Event source with consecutive occurrences at the given intervals. -- Should more than one event be scheduled to occur in any sampling -- interval, only the first will in fact occur to avoid an event backlog. afterEach :: Monad m => [(Time, b)] -> SF m a (Event b) -- | Event source with consecutive occurrences at the given intervals. -- Should more than one event be scheduled to occur in any sampling -- interval, the output list will contain all events produced during that -- interval. afterEachCat :: Monad m => [(Time, b)] -> SF m a (Event [b]) -- | Apply an MSF to every input. Freezes temporarily if the input -- is NoEvent, and continues as soon as an Event is -- received. mapEventS :: Monad m => MSF m a b -> MSF m (Event a) (Event b) eventToMaybe :: Event a -> Maybe a boolToEvent :: Bool -> Event () edge :: Monad m => SF m Bool (Event ()) iEdge :: Monad m => Bool -> SF m Bool (Event ()) -- | Like edge, but parameterized on the tag value. -- -- From Yampa edgeTag :: Monad m => a -> SF m Bool (Event a) -- | Edge detector particularized for detecting transtitions on a -- Maybe signal from Nothing to Just. -- -- From Yampa edgeJust :: Monad m => SF m (Maybe a) (Event a) edgeBy :: Monad m => (a -> a -> Maybe b) -> a -> SF m a (Event b) maybeToEvent :: Maybe a -> Event a edgeFrom :: Monad m => Bool -> SF m Bool (Event ()) -- | Suppression of initial (at local time 0) event. notYet :: Monad m => SF m (Event a) (Event a) -- | Suppress all but the first event. once :: Monad m => SF m (Event a) (Event a) -- | Suppress all but the first n events. takeEvents :: Monad m => Int -> SF m (Event a) (Event a) -- | Suppress first n events. dropEvents :: Monad m => Int -> SF m (Event a) (Event a) noEvent :: Event a -- | Suppress any event in the first component of a pair. noEventFst :: (Event a, b) -> (Event c, b) -- | Suppress any event in the second component of a pair. noEventSnd :: (a, Event b) -> (a, Event c) event :: a -> (b -> a) -> Event b -> a fromEvent :: Event p -> p isEvent :: Event a -> Bool isNoEvent :: Event a -> Bool tag :: Event a -> b -> Event b -- | Tags an (occurring) event with a value ("replacing" the old value). -- Same as tag with the arguments swapped. -- -- Applicative-based definition: tagWith = (<$) tagWith :: b -> Event a -> Event b -- | Attaches an extra value to the value of an occurring event. attach :: Event a -> b -> Event (a, b) -- | Left-biased event merge (always prefer left event, if present). lMerge :: Event a -> Event a -> Event a -- | Right-biased event merge (always prefer right event, if present). rMerge :: Event a -> Event a -> Event a merge :: Event a -> Event a -> Event a mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a -- | A generic event merge-map utility that maps event occurrences, merging -- the results. The first three arguments are mapping functions, the -- third of which will only be used when both events are present. -- Therefore, mergeBy = mapMerge id id -- -- Applicative-based definition: mapMerge lf rf lrf le re = (f $ -- le * re) | (lf $ le) | (rf $ re) mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c -- | Merge a list of events; foremost event has priority. -- -- Foldable-based definition: mergeEvents :: Foldable t => t (Event a) -- -> Event a mergeEvents = asum mergeEvents :: [Event a] -> Event a -- | Collect simultaneous event occurrences; no event if none. -- -- Traverable-based definition: catEvents :: Foldable t => t (Event a) -- -> Event (t a) carEvents e = if (null e) then NoEvent else -- (sequenceA e) catEvents :: [Event a] -> Event [a] -- | Join (conjunction) of two events. Only produces an event if both -- events exist. -- -- Applicative-based definition: joinE = liftA2 (,) joinE :: Event a -> Event b -> Event (a, b) -- | Split event carrying pairs into two events. splitE :: Event (a, b) -> (Event a, Event b) -- | Filter out events that don't satisfy some predicate. filterE :: (a -> Bool) -> Event a -> Event a -- | Combined event mapping and filtering. Note: since Event is a -- Functor, see fmap for a simpler version of this function -- with no filtering. mapFilterE :: (a -> Maybe b) -> Event a -> Event b -- | Enable/disable event occurences based on an external condition. gate :: Event a -> Bool -> Event a switch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b dSwitch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b parB :: Monad m => [SF m a b] -> SF m a [b] dpSwitchB :: (Functor m, Monad m, Traversable col) => col (SF m a b) -> SF m (a, col b) (Event c) -> (col (SF m a b) -> c -> SF m a (col b)) -> SF m a (col b) parC :: Monad m => SF m a b -> SF m [a] [b] hold :: Monad m => a -> SF m (Event a) a -- | Accumulator parameterized by the accumulation function. accumBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) (Event b) accumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b loopPre :: Monad m => c -> SF m (a, c) (b, c) -> SF m a b integral :: (Monad m, VectorSpace a s) => SF m a a integralFrom :: (Monad m, VectorSpace a s) => a -> SF m a a derivative :: (Monad m, VectorSpace a s) => SF m a a derivativeFrom :: (Monad m, VectorSpace a s) => a -> SF m a a iterFrom :: Monad m => (a -> a -> DTime -> b -> b) -> b -> SF m a b occasionally :: MonadRandom m => Time -> b -> SF m a (Event b) reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF Identity a b -> m () -- | Evaluate an SF, and return an output and an initialized SF. -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalAtZero :: SF Identity a b -> a -> (b, SF Identity a b) -- | Evaluate an initialized SF, and return an output and a continuation. -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalAt :: SF Identity a b -> DTime -> a -> (b, SF Identity a b) -- | Given a signal function and time delta, it moves the signal function -- into the future, returning a new uninitialized SF and the initial -- output. -- -- While the input sample refers to the present, the time delta refers to -- the future (or to the time between the current sample and the next -- sample). -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalFuture :: SF Identity a b -> a -> DTime -> (b, SF Identity a b) replaceOnce :: Monad m => a -> SF m a a dup :: b -> (b, b) -- | Any instance of ArrowApply can be made into an instance of -- ArrowChoice by defining left = leftApp. leftApp :: ArrowApply a => a b c -> a (Either b d) (Either c d) -- | Postcomposition with a pure function (right-to-left variant). (^<<) :: Arrow a => (c -> d) -> a b c -> a b d infixr 1 ^<< -- | Precomposition with a pure function (right-to-left variant). (<<^) :: Arrow a => a c d -> (b -> c) -> a b d infixr 1 <<^ -- | Postcomposition with a pure function. (>>^) :: Arrow a => a b c -> (c -> d) -> a b d infixr 1 >>^ -- | Precomposition with a pure function. (^>>) :: Arrow a => (b -> c) -> a c d -> a b d infixr 1 ^>> -- | The identity arrow, which plays the role of return in arrow -- notation. returnA :: Arrow a => a b b -- | The basic arrow class. -- -- Instances should satisfy the following laws: -- -- -- -- where -- --
--   assoc ((a,b),c) = (a,(b,c))
--   
-- -- The other combinators have sensible default definitions, which may be -- overridden for efficiency. class Category a => Arrow (a :: Type -> Type -> Type) -- | Lift a function to an arrow. arr :: Arrow a => (b -> c) -> a b c -- | Send the first component of the input through the argument arrow, and -- copy the rest unchanged to the output. first :: Arrow a => a b c -> a (b, d) (c, d) -- | A mirror image of first. -- -- The default definition may be overridden with a more efficient version -- if desired. second :: Arrow a => a b c -> a (d, b) (d, c) -- | Split the input between the two argument arrows and combine their -- output. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient version -- if desired. (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c') -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& infixr 3 *** -- | Kleisli arrows of a monad. newtype Kleisli (m :: Type -> Type) a b Kleisli :: (a -> m b) -> Kleisli (m :: Type -> Type) a b [runKleisli] :: Kleisli (m :: Type -> Type) a b -> a -> m b class Arrow a => ArrowZero (a :: Type -> Type -> Type) zeroArrow :: ArrowZero a => a b c -- | A monoid on arrows. class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type) -- | An associative operation with identity zeroArrow. (<+>) :: ArrowPlus a => a b c -> a b c -> a b c infixr 5 <+> -- | Choice, for arrows that support it. This class underlies the -- if and case constructs in arrow notation. -- -- Instances should satisfy the following laws: -- -- -- -- where -- --
--   assocsum (Left (Left x)) = Left x
--   assocsum (Left (Right y)) = Right (Left y)
--   assocsum (Right z) = Right (Right z)
--   
-- -- The other combinators have sensible default definitions, which may be -- overridden for efficiency. class Arrow a => ArrowChoice (a :: Type -> Type -> Type) -- | Feed marked inputs through the argument arrow, passing the rest -- through unchanged to the output. left :: ArrowChoice a => a b c -> a (Either b d) (Either c d) -- | A mirror image of left. -- -- The default definition may be overridden with a more efficient version -- if desired. right :: ArrowChoice a => a b c -> a (Either d b) (Either d c) -- | Split the input between the two argument arrows, retagging and merging -- their outputs. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient version -- if desired. (+++) :: ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c') -- | Fanin: Split the input between the two argument arrows and merge their -- outputs. -- -- The default definition may be overridden with a more efficient version -- if desired. (|||) :: ArrowChoice a => a b d -> a c d -> a (Either b c) d infixr 2 ||| infixr 2 +++ -- | Some arrows allow application of arrow inputs to other inputs. -- Instances should satisfy the following laws: -- -- -- -- Such arrows are equivalent to monads (see ArrowMonad). class Arrow a => ArrowApply (a :: Type -> Type -> Type) app :: ArrowApply a => a (a b c, b) c -- | The ArrowApply class is equivalent to Monad: any monad -- gives rise to a Kleisli arrow, and any instance of -- ArrowApply defines a monad. newtype ArrowMonad (a :: Type -> Type -> Type) b ArrowMonad :: a () b -> ArrowMonad (a :: Type -> Type -> Type) b -- | The loop operator expresses computations in which an output -- value is fed back as input, although the computation occurs only once. -- It underlies the rec value recursion construct in arrow -- notation. loop should satisfy the following laws: -- -- -- -- where -- --
--   assoc ((a,b),c) = (a,(b,c))
--   unassoc (a,(b,c)) = ((a,b),c)
--   
class Arrow a => ArrowLoop (a :: Type -> Type -> Type) loop :: ArrowLoop a => a (b, d) (c, d) -> a b c -- | Left-to-right composition (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c infixr 1 >>> -- | Right-to-left composition (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c infixr 1 <<< -- | Outputs every input sample, with a given message prefix, when a -- condition is met, and waits for some input / enter to continue. pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a -- | Outputs every input sample, with a given message prefix, using an -- auxiliary printing function, when a condition is met. traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a -- | Outputs every input sample, with a given message prefix, using an -- auxiliary printing function. traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a -- | Generate outputs using a step-wise generation function and an initial -- value. unfold :: forall (m :: Type -> Type) a b. Monad m => (a -> (b, a)) -> a -> MSF m () b -- | Applies a transfer function to the input and an accumulator, returning -- the updated accumulator and output. mealy :: forall (m :: Type -> Type) a s b. Monad m => (a -> s -> (b, s)) -> s -> MSF m a b -- | Applies a function to the input and an accumulator, outputting the -- updated accumulator. Equal to f s0 -> feedback s0 $ arr -- (uncurry f >>> dup). accumulateWith :: forall (m :: Type -> Type) a s. Monad m => (a -> s -> s) -> s -> MSF m a s -- | Accumulate the inputs, starting from an initial monoid value. mappendFrom :: forall n (m :: Type -> Type). (Monoid n, Monad m) => n -> MSF m n n -- | Accumulate the inputs, starting from mempty. mappendS :: forall n (m :: Type -> Type). (Monoid n, Monad m) => MSF m n n -- | Sums the inputs, starting from an initial vector. sumFrom :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => v -> MSF m v v -- | Sums the inputs, starting from zero. sumS :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => MSF m v v -- | Count the number of simulation steps. Produces 1, 2, 3,... count :: forall n (m :: Type -> Type) a. (Num n, Monad m) => MSF m a n -- | Buffers and returns the elements in FIFO order, returning -- Nothing whenever the buffer is empty. fifo :: forall (m :: Type -> Type) a. Monad m => MSF m [a] (Maybe a) -- | Preprends a fixed output to an MSF, shifting the output. next :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b -- | Preprends a fixed output to an MSF. The first input is -- completely ignored. iPost :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b -- | Delay a signal by one sample. iPre :: forall (m :: Type -> Type) a. Monad m => a -> MSF m a a -- | Produces an additional side effect and passes the input unchanged. withSideEffect_ :: Monad m => m b -> MSF m a a -- | Applies a function to produce an additional side effect and passes the -- input unchanged. withSideEffect :: Monad m => (a -> m b) -> MSF m a a -- | Apply an MSF to every input. Freezes temporarily if the input -- is Nothing, and continues as soon as a Just is received. mapMaybeS :: forall (m :: Type -> Type) a b. Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b) -- | A stream is an MSF that produces outputs, while ignoring the -- input. It can obtain the values from a monadic context. type MStream (m :: Type -> Type) a = MSF m () a -- | A sink is an MSF that consumes inputs, while producing no -- output. It can consume the values with side effects. type MSink (m :: Type -> Type) a = MSF m a () -- | Apply trans-monadic actions (in an arbitrary way). -- -- This is just a convenience function when you have a function to move -- across monads, because the signature of morphGS is a bit -- complex. morphS :: (Monad m2, Monad m1) => (forall c. () => m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b -- | Lift inner monadic actions in monad stacks. liftTransS :: forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a b. (MonadTrans t, Monad m, Monad (t m)) => MSF m a b -> MSF (t m) a b -- | Lift the second MSF into the monad of the first. (>>>^) :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) a b c. MonadBase m1 m2 => MSF m2 a b -> MSF m1 b c -> MSF m2 a c -- | Lift the first MSF into the monad of the second. (^>>>) :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) a b c. MonadBase m1 m2 => MSF m1 a b -> MSF m2 b c -> MSF m2 a c -- | Lift innermost monadic actions in monad stack (generalisation of -- liftIO). liftBaseS :: forall (m2 :: Type -> Type) (m1 :: Type -> Type) a b. (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b -- | Monadic lifting from one monad into another liftBaseM :: forall (m2 :: Type -> Type) m1 a b. (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b -- | Apply a monadic transformation to every element of the input stream. -- -- Generalisation of arr from Arrow to monadic functions. arrM :: Monad m => (a -> m b) -> MSF m a b -- | Lifts a monadic computation into a Stream. constM :: Monad m => m b -> MSF m a b -- | Apply a monadic stream function to a list. -- -- Because the result is in a monad, it may be necessary to traverse the -- whole list to evaluate the value in the results to WHNF. For example, -- if the monad is the maybe monad, this may not produce anything if the -- MSF produces Nothing at any point, so the output stream -- cannot consumed progressively. -- -- To explore the output progressively, use arrM and -- (>>>)', together with some action that -- consumes/actuates on the output. -- -- This is called runSF in Liu, Cheng, Hudak, "Causal -- Commutative Arrows and Their Optimization" embed :: Monad m => MSF m a b -> [a] -> m [b] -- | Well-formed looped connection of an output component as a future -- input. feedback :: forall (m :: Type -> Type) c a b. Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b -- | Generic lifting of a morphism to the level of MSFs. -- -- Natural transformation to the level of MSFs. -- -- Mathematical background: The type a -> m (b, c) is -- a functor in c, and MSF m a b is its greatest -- fixpoint, i.e. it is isomorphic to the type a -> m (b, MSF m a -- b), by definition. The types m, a and -- b are parameters of the functor. Taking a fixpoint is -- functorial itself, meaning that a morphism (a natural transformation) -- of two such functors gives a morphism (an ordinary function) of their -- fixpoints. -- -- This is in a sense the most general "abstract" lifting function, i.e. -- the most general one that only changes input, output and side effect -- types, and doesn't influence control flow. Other handling functions -- like exception handling or ListT broadcasting necessarily -- change control flow. morphGS :: Monad m2 => (forall c. () => (a1 -> m1 (b1, c)) -> a2 -> m2 (b2, c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2 -- | Stepwise, side-effectful MSFs without implicit knowledge of -- time. -- -- MSFs should be applied to streams or executed indefinitely or -- until they terminate. See reactimate and reactimateB -- for details. In general, calling the value constructor MSF or -- the function unMSF is discouraged. data MSF (m :: Type -> Type) a b -- | Vector space type relation. -- -- A vector space is a set (type) closed under addition and -- multiplication by a scalar. The type of the scalar is the field -- of the vector space, and it is said that v is a vector space -- over a. -- -- The encoding uses a type class |VectorSpace| v a, where -- v represents the type of the vectors and a -- represents the types of the scalars. class (Eq a, Floating a) => VectorSpace v a | v -> a -- | Vector with no magnitude (unit for addition). zeroVector :: VectorSpace v a => v -- | Multiplication by a scalar. (*^) :: VectorSpace v a => a -> v -> v -- | Division by a scalar. (^/) :: VectorSpace v a => v -> a -> v -- | Vector addition (^+^) :: VectorSpace v a => v -> v -> v -- | Vector subtraction (^-^) :: VectorSpace v a => v -> v -> v -- | Vector negation. Addition with a negated vector should be same as -- subtraction. negateVector :: VectorSpace v a => v -> v -- | Dot product (also known as scalar or inner product). -- -- For two vectors, mathematically represented as a = -- a1,a2,...,an and b = b1,b2,...,bn, the dot product is -- a . b = a1*b1 + a2*b2 + ... + an*bn. -- -- Some properties are derived from this. The dot product of a vector -- with itself is the square of its magnitude (norm), and the dot -- product of two orthogonal vectors is zero. dot :: VectorSpace v a => v -> v -> a -- | Vector's norm (also known as magnitude). -- -- For a vector represented mathematically as a = a1,a2,...,an, -- the norm is the square root of a1^2 + a2^2 + ... + an^2. norm :: VectorSpace v a => v -> a -- | Return a vector with the same origin and orientation (angle), but such -- that the norm is one (the unit for multiplication by a scalar). normalize :: VectorSpace v a => v -> v infix 7 `dot` infixl 6 ^-^ infixl 6 ^+^ infixl 9 ^/ infixr 9 *^ instance GHC.Show.Show a => GHC.Show.Show (FRP.BearRiver.Event a) instance GHC.Classes.Eq a => GHC.Classes.Eq (FRP.BearRiver.Event a) instance GHC.Base.Functor FRP.BearRiver.Event instance GHC.Base.Applicative FRP.BearRiver.Event instance GHC.Base.Monad FRP.BearRiver.Event module FRP.Yampa -- | Any instance of ArrowApply can be made into an instance of -- ArrowChoice by defining left = leftApp. leftApp :: ArrowApply a => a b c -> a (Either b d) (Either c d) -- | Postcomposition with a pure function (right-to-left variant). (^<<) :: Arrow a => (c -> d) -> a b c -> a b d infixr 1 ^<< -- | Precomposition with a pure function (right-to-left variant). (<<^) :: Arrow a => a c d -> (b -> c) -> a b d infixr 1 <<^ -- | Postcomposition with a pure function. (>>^) :: Arrow a => a b c -> (c -> d) -> a b d infixr 1 >>^ -- | Precomposition with a pure function. (^>>) :: Arrow a => (b -> c) -> a c d -> a b d infixr 1 ^>> -- | The identity arrow, which plays the role of return in arrow -- notation. returnA :: Arrow a => a b b -- | The basic arrow class. -- -- Instances should satisfy the following laws: -- -- -- -- where -- --
--   assoc ((a,b),c) = (a,(b,c))
--   
-- -- The other combinators have sensible default definitions, which may be -- overridden for efficiency. class Category a => Arrow (a :: Type -> Type -> Type) -- | Lift a function to an arrow. arr :: Arrow a => (b -> c) -> a b c -- | Send the first component of the input through the argument arrow, and -- copy the rest unchanged to the output. first :: Arrow a => a b c -> a (b, d) (c, d) -- | A mirror image of first. -- -- The default definition may be overridden with a more efficient version -- if desired. second :: Arrow a => a b c -> a (d, b) (d, c) -- | Split the input between the two argument arrows and combine their -- output. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient version -- if desired. (***) :: Arrow a => a b c -> a b' c' -> a (b, b') (c, c') -- | Fanout: send the input to both argument arrows and combine their -- output. -- -- The default definition may be overridden with a more efficient version -- if desired. (&&&) :: Arrow a => a b c -> a b c' -> a b (c, c') infixr 3 &&& infixr 3 *** -- | Kleisli arrows of a monad. newtype Kleisli (m :: Type -> Type) a b Kleisli :: (a -> m b) -> Kleisli (m :: Type -> Type) a b [runKleisli] :: Kleisli (m :: Type -> Type) a b -> a -> m b class Arrow a => ArrowZero (a :: Type -> Type -> Type) zeroArrow :: ArrowZero a => a b c -- | A monoid on arrows. class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type) -- | An associative operation with identity zeroArrow. (<+>) :: ArrowPlus a => a b c -> a b c -> a b c infixr 5 <+> -- | Choice, for arrows that support it. This class underlies the -- if and case constructs in arrow notation. -- -- Instances should satisfy the following laws: -- -- -- -- where -- --
--   assocsum (Left (Left x)) = Left x
--   assocsum (Left (Right y)) = Right (Left y)
--   assocsum (Right z) = Right (Right z)
--   
-- -- The other combinators have sensible default definitions, which may be -- overridden for efficiency. class Arrow a => ArrowChoice (a :: Type -> Type -> Type) -- | Feed marked inputs through the argument arrow, passing the rest -- through unchanged to the output. left :: ArrowChoice a => a b c -> a (Either b d) (Either c d) -- | A mirror image of left. -- -- The default definition may be overridden with a more efficient version -- if desired. right :: ArrowChoice a => a b c -> a (Either d b) (Either d c) -- | Split the input between the two argument arrows, retagging and merging -- their outputs. Note that this is in general not a functor. -- -- The default definition may be overridden with a more efficient version -- if desired. (+++) :: ArrowChoice a => a b c -> a b' c' -> a (Either b b') (Either c c') -- | Fanin: Split the input between the two argument arrows and merge their -- outputs. -- -- The default definition may be overridden with a more efficient version -- if desired. (|||) :: ArrowChoice a => a b d -> a c d -> a (Either b c) d infixr 2 ||| infixr 2 +++ -- | Some arrows allow application of arrow inputs to other inputs. -- Instances should satisfy the following laws: -- -- -- -- Such arrows are equivalent to monads (see ArrowMonad). class Arrow a => ArrowApply (a :: Type -> Type -> Type) app :: ArrowApply a => a (a b c, b) c -- | The ArrowApply class is equivalent to Monad: any monad -- gives rise to a Kleisli arrow, and any instance of -- ArrowApply defines a monad. newtype ArrowMonad (a :: Type -> Type -> Type) b ArrowMonad :: a () b -> ArrowMonad (a :: Type -> Type -> Type) b -- | The loop operator expresses computations in which an output -- value is fed back as input, although the computation occurs only once. -- It underlies the rec value recursion construct in arrow -- notation. loop should satisfy the following laws: -- -- -- -- where -- --
--   assoc ((a,b),c) = (a,(b,c))
--   unassoc (a,(b,c)) = ((a,b),c)
--   
class Arrow a => ArrowLoop (a :: Type -> Type -> Type) loop :: ArrowLoop a => a (b, d) (c, d) -> a b c -- | Left-to-right composition (>>>) :: forall k cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c infixr 1 >>> -- | Right-to-left composition (<<<) :: forall k cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c infixr 1 <<< -- | Outputs every input sample, with a given message prefix, when a -- condition is met, and waits for some input / enter to continue. pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a -- | Outputs every input sample, with a given message prefix, using an -- auxiliary printing function, when a condition is met. traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a -- | Outputs every input sample, with a given message prefix, using an -- auxiliary printing function. traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a -- | Generate outputs using a step-wise generation function and an initial -- value. unfold :: forall (m :: Type -> Type) a b. Monad m => (a -> (b, a)) -> a -> MSF m () b -- | Applies a transfer function to the input and an accumulator, returning -- the updated accumulator and output. mealy :: forall (m :: Type -> Type) a s b. Monad m => (a -> s -> (b, s)) -> s -> MSF m a b -- | Applies a function to the input and an accumulator, outputting the -- updated accumulator. Equal to f s0 -> feedback s0 $ arr -- (uncurry f >>> dup). accumulateWith :: forall (m :: Type -> Type) a s. Monad m => (a -> s -> s) -> s -> MSF m a s -- | Accumulate the inputs, starting from an initial monoid value. mappendFrom :: forall n (m :: Type -> Type). (Monoid n, Monad m) => n -> MSF m n n -- | Accumulate the inputs, starting from mempty. mappendS :: forall n (m :: Type -> Type). (Monoid n, Monad m) => MSF m n n -- | Sums the inputs, starting from an initial vector. sumFrom :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => v -> MSF m v v -- | Sums the inputs, starting from zero. sumS :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => MSF m v v -- | Count the number of simulation steps. Produces 1, 2, 3,... count :: forall n (m :: Type -> Type) a. (Num n, Monad m) => MSF m a n -- | Buffers and returns the elements in FIFO order, returning -- Nothing whenever the buffer is empty. fifo :: forall (m :: Type -> Type) a. Monad m => MSF m [a] (Maybe a) -- | Preprends a fixed output to an MSF, shifting the output. next :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b -- | Preprends a fixed output to an MSF. The first input is -- completely ignored. iPost :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b -- | Delay a signal by one sample. iPre :: forall (m :: Type -> Type) a. Monad m => a -> MSF m a a -- | Produces an additional side effect and passes the input unchanged. withSideEffect_ :: Monad m => m b -> MSF m a a -- | Applies a function to produce an additional side effect and passes the -- input unchanged. withSideEffect :: Monad m => (a -> m b) -> MSF m a a -- | Apply an MSF to every input. Freezes temporarily if the input -- is Nothing, and continues as soon as a Just is received. mapMaybeS :: forall (m :: Type -> Type) a b. Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b) -- | A stream is an MSF that produces outputs, while ignoring the -- input. It can obtain the values from a monadic context. type MStream (m :: Type -> Type) a = MSF m () a -- | A sink is an MSF that consumes inputs, while producing no -- output. It can consume the values with side effects. type MSink (m :: Type -> Type) a = MSF m a () -- | Apply trans-monadic actions (in an arbitrary way). -- -- This is just a convenience function when you have a function to move -- across monads, because the signature of morphGS is a bit -- complex. morphS :: (Monad m2, Monad m1) => (forall c. () => m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b -- | Lift inner monadic actions in monad stacks. liftTransS :: forall (t :: (Type -> Type) -> Type -> Type) (m :: Type -> Type) a b. (MonadTrans t, Monad m, Monad (t m)) => MSF m a b -> MSF (t m) a b -- | Lift the second MSF into the monad of the first. (>>>^) :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) a b c. MonadBase m1 m2 => MSF m2 a b -> MSF m1 b c -> MSF m2 a c -- | Lift the first MSF into the monad of the second. (^>>>) :: forall (m1 :: Type -> Type) (m2 :: Type -> Type) a b c. MonadBase m1 m2 => MSF m1 a b -> MSF m2 b c -> MSF m2 a c -- | Lift innermost monadic actions in monad stack (generalisation of -- liftIO). liftBaseS :: forall (m2 :: Type -> Type) (m1 :: Type -> Type) a b. (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b -- | Monadic lifting from one monad into another liftBaseM :: forall (m2 :: Type -> Type) m1 a b. (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b -- | Apply a monadic transformation to every element of the input stream. -- -- Generalisation of arr from Arrow to monadic functions. arrM :: Monad m => (a -> m b) -> MSF m a b -- | Lifts a monadic computation into a Stream. constM :: Monad m => m b -> MSF m a b -- | Apply a monadic stream function to a list. -- -- Because the result is in a monad, it may be necessary to traverse the -- whole list to evaluate the value in the results to WHNF. For example, -- if the monad is the maybe monad, this may not produce anything if the -- MSF produces Nothing at any point, so the output stream -- cannot consumed progressively. -- -- To explore the output progressively, use arrM and -- (>>>)', together with some action that -- consumes/actuates on the output. -- -- This is called runSF in Liu, Cheng, Hudak, "Causal -- Commutative Arrows and Their Optimization" embed :: Monad m => MSF m a b -> [a] -> m [b] -- | Well-formed looped connection of an output component as a future -- input. feedback :: forall (m :: Type -> Type) c a b. Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b -- | Generic lifting of a morphism to the level of MSFs. -- -- Natural transformation to the level of MSFs. -- -- Mathematical background: The type a -> m (b, c) is -- a functor in c, and MSF m a b is its greatest -- fixpoint, i.e. it is isomorphic to the type a -> m (b, MSF m a -- b), by definition. The types m, a and -- b are parameters of the functor. Taking a fixpoint is -- functorial itself, meaning that a morphism (a natural transformation) -- of two such functors gives a morphism (an ordinary function) of their -- fixpoints. -- -- This is in a sense the most general "abstract" lifting function, i.e. -- the most general one that only changes input, output and side effect -- types, and doesn't influence control flow. Other handling functions -- like exception handling or ListT broadcasting necessarily -- change control flow. morphGS :: Monad m2 => (forall c. () => (a1 -> m1 (b1, c)) -> a2 -> m2 (b2, c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2 -- | Stepwise, side-effectful MSFs without implicit knowledge of -- time. -- -- MSFs should be applied to streams or executed indefinitely or -- until they terminate. See reactimate and reactimateB -- for details. In general, calling the value constructor MSF or -- the function unMSF is discouraged. data MSF (m :: Type -> Type) a b -- | Vector space type relation. -- -- A vector space is a set (type) closed under addition and -- multiplication by a scalar. The type of the scalar is the field -- of the vector space, and it is said that v is a vector space -- over a. -- -- The encoding uses a type class |VectorSpace| v a, where -- v represents the type of the vectors and a -- represents the types of the scalars. class (Eq a, Floating a) => VectorSpace v a | v -> a -- | Vector with no magnitude (unit for addition). zeroVector :: VectorSpace v a => v -- | Multiplication by a scalar. (*^) :: VectorSpace v a => a -> v -> v -- | Division by a scalar. (^/) :: VectorSpace v a => v -> a -> v -- | Vector addition (^+^) :: VectorSpace v a => v -> v -> v -- | Vector subtraction (^-^) :: VectorSpace v a => v -> v -> v -- | Vector negation. Addition with a negated vector should be same as -- subtraction. negateVector :: VectorSpace v a => v -> v -- | Dot product (also known as scalar or inner product). -- -- For two vectors, mathematically represented as a = -- a1,a2,...,an and b = b1,b2,...,bn, the dot product is -- a . b = a1*b1 + a2*b2 + ... + an*bn. -- -- Some properties are derived from this. The dot product of a vector -- with itself is the square of its magnitude (norm), and the dot -- product of two orthogonal vectors is zero. dot :: VectorSpace v a => v -> v -> a -- | Vector's norm (also known as magnitude). -- -- For a vector represented mathematically as a = a1,a2,...,an, -- the norm is the square root of a1^2 + a2^2 + ... + an^2. norm :: VectorSpace v a => v -> a -- | Return a vector with the same origin and orientation (angle), but such -- that the norm is one (the unit for multiplication by a scalar). normalize :: VectorSpace v a => v -> v infix 7 `dot` infixl 6 ^-^ infixl 6 ^+^ infixl 9 ^/ infixr 9 *^ -- | A value that may or may not exist. -- -- Used to represent discrete-time signals. data Event a Event :: a -> Event a NoEvent :: Event a -- | Information on the progress of time. type ClockInfo m = ReaderT DTime m -- | Time deltas or increments (conceptually positive). type DTime = Double -- | Absolute time. type Time = Double arrPrim :: Monad m => (a -> b) -> SF m a b arrEPrim :: Monad m => (Event a -> b) -> SF m (Event a) b identity :: Monad m => SF m a a constant :: Monad m => b -> SF m a b localTime :: Monad m => SF m a Time time :: Monad m => SF m a Time -- | Initialization operator (cf. Lustre/Lucid Synchrone). -- -- The output at time zero is the first argument, and from that point on -- it behaves like the signal function passed as second argument. (-->) :: Monad m => b -> SF m a b -> SF m a b infixr 0 --> -- | Output pre-insert operator. -- -- Insert a sample in the output, and from that point on, behave like the -- given sf. (-:>) :: Monad m => b -> SF m a b -> SF m a b infixr 0 -:> -- | Input initialization operator. -- -- The input at time zero is the first argument, and from that point on -- it behaves like the signal function passed as second argument. (>--) :: Monad m => a -> SF m a b -> SF m a b infixr 0 >-- (>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b infixr 0 >=- initially :: Monad m => a -> SF m a a sscan :: Monad m => (b -> a -> b) -> b -> SF m a b sscanPrim :: Monad m => (c -> a -> Maybe (c, b)) -> c -> b -> SF m a b -- | Event source that never occurs. never :: Monad m => SF m a (Event b) -- | Event source with a single occurrence at time 0. The value of the -- event is given by the function argument. now :: Monad m => b -> SF m a (Event b) after :: Monad m => Time -> b -> SF m a (Event b) repeatedly :: Monad m => Time -> b -> SF m a (Event b) -- | Event source with consecutive occurrences at the given intervals. -- Should more than one event be scheduled to occur in any sampling -- interval, only the first will in fact occur to avoid an event backlog. afterEach :: Monad m => [(Time, b)] -> SF m a (Event b) -- | Event source with consecutive occurrences at the given intervals. -- Should more than one event be scheduled to occur in any sampling -- interval, the output list will contain all events produced during that -- interval. afterEachCat :: Monad m => [(Time, b)] -> SF m a (Event [b]) -- | Apply an MSF to every input. Freezes temporarily if the input -- is NoEvent, and continues as soon as an Event is -- received. mapEventS :: Monad m => MSF m a b -> MSF m (Event a) (Event b) eventToMaybe :: Event a -> Maybe a boolToEvent :: Bool -> Event () edge :: Monad m => SF m Bool (Event ()) iEdge :: Monad m => Bool -> SF m Bool (Event ()) -- | Like edge, but parameterized on the tag value. -- -- From Yampa edgeTag :: Monad m => a -> SF m Bool (Event a) -- | Edge detector particularized for detecting transtitions on a -- Maybe signal from Nothing to Just. -- -- From Yampa edgeJust :: Monad m => SF m (Maybe a) (Event a) edgeBy :: Monad m => (a -> a -> Maybe b) -> a -> SF m a (Event b) maybeToEvent :: Maybe a -> Event a edgeFrom :: Monad m => Bool -> SF m Bool (Event ()) -- | Suppression of initial (at local time 0) event. notYet :: Monad m => SF m (Event a) (Event a) -- | Suppress all but the first event. once :: Monad m => SF m (Event a) (Event a) -- | Suppress all but the first n events. takeEvents :: Monad m => Int -> SF m (Event a) (Event a) -- | Suppress first n events. dropEvents :: Monad m => Int -> SF m (Event a) (Event a) noEvent :: Event a -- | Suppress any event in the first component of a pair. noEventFst :: (Event a, b) -> (Event c, b) -- | Suppress any event in the second component of a pair. noEventSnd :: (a, Event b) -> (a, Event c) event :: a -> (b -> a) -> Event b -> a fromEvent :: Event p -> p isEvent :: Event a -> Bool isNoEvent :: Event a -> Bool tag :: Event a -> b -> Event b -- | Tags an (occurring) event with a value ("replacing" the old value). -- Same as tag with the arguments swapped. -- -- Applicative-based definition: tagWith = (<$) tagWith :: b -> Event a -> Event b -- | Attaches an extra value to the value of an occurring event. attach :: Event a -> b -> Event (a, b) -- | Left-biased event merge (always prefer left event, if present). lMerge :: Event a -> Event a -> Event a -- | Right-biased event merge (always prefer right event, if present). rMerge :: Event a -> Event a -> Event a merge :: Event a -> Event a -> Event a mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a -- | A generic event merge-map utility that maps event occurrences, merging -- the results. The first three arguments are mapping functions, the -- third of which will only be used when both events are present. -- Therefore, mergeBy = mapMerge id id -- -- Applicative-based definition: mapMerge lf rf lrf le re = (f $ -- le * re) | (lf $ le) | (rf $ re) mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c -- | Merge a list of events; foremost event has priority. -- -- Foldable-based definition: mergeEvents :: Foldable t => t (Event a) -- -> Event a mergeEvents = asum mergeEvents :: [Event a] -> Event a -- | Collect simultaneous event occurrences; no event if none. -- -- Traverable-based definition: catEvents :: Foldable t => t (Event a) -- -> Event (t a) carEvents e = if (null e) then NoEvent else -- (sequenceA e) catEvents :: [Event a] -> Event [a] -- | Join (conjunction) of two events. Only produces an event if both -- events exist. -- -- Applicative-based definition: joinE = liftA2 (,) joinE :: Event a -> Event b -> Event (a, b) -- | Split event carrying pairs into two events. splitE :: Event (a, b) -> (Event a, Event b) -- | Filter out events that don't satisfy some predicate. filterE :: (a -> Bool) -> Event a -> Event a -- | Combined event mapping and filtering. Note: since Event is a -- Functor, see fmap for a simpler version of this function -- with no filtering. mapFilterE :: (a -> Maybe b) -> Event a -> Event b -- | Enable/disable event occurences based on an external condition. gate :: Event a -> Bool -> Event a switch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b dSwitch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b parB :: Monad m => [SF m a b] -> SF m a [b] dpSwitchB :: (Functor m, Monad m, Traversable col) => col (SF m a b) -> SF m (a, col b) (Event c) -> (col (SF m a b) -> c -> SF m a (col b)) -> SF m a (col b) parC :: Monad m => SF m a b -> SF m [a] [b] hold :: Monad m => a -> SF m (Event a) a -- | Accumulator parameterized by the accumulation function. accumBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) (Event b) accumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b loopPre :: Monad m => c -> SF m (a, c) (b, c) -> SF m a b integral :: (Monad m, VectorSpace a s) => SF m a a integralFrom :: (Monad m, VectorSpace a s) => a -> SF m a a derivative :: (Monad m, VectorSpace a s) => SF m a a derivativeFrom :: (Monad m, VectorSpace a s) => a -> SF m a a iterFrom :: Monad m => (a -> a -> DTime -> b -> b) -> b -> SF m a b occasionally :: MonadRandom m => Time -> b -> SF m a (Event b) reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF Identity a b -> m () -- | Evaluate an SF, and return an output and an initialized SF. -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalAtZero :: SF Identity a b -> a -> (b, SF Identity a b) -- | Evaluate an initialized SF, and return an output and a continuation. -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalAt :: SF Identity a b -> DTime -> a -> (b, SF Identity a b) -- | Given a signal function and time delta, it moves the signal function -- into the future, returning a new uninitialized SF and the initial -- output. -- -- While the input sample refers to the present, the time delta refers to -- the future (or to the time between the current sample and the next -- sample). -- -- WARN: Do not use this function for standard simulation. This -- function is intended only for debugging/testing. Apart from being -- potentially slower and consuming more memory, it also breaks the FRP -- abstraction by making samples discrete and step based. evalFuture :: SF Identity a b -> a -> DTime -> (b, SF Identity a b) replaceOnce :: Monad m => a -> SF m a a dup :: b -> (b, b) -- | Signal function (conceptually, a function between signals that -- respects causality). type SF = SF Identity -- | Future signal function (conceptually, a function between fugure -- signals that respects causality). -- -- A future signal is a signal that is only defined for positive times. type FutureSF = SF Identity