Copyright | (c) Ivan Perez 2019-2022 (c) Ivan Perez and Manuel Baerenz 2016-2018 |
---|---|
License | BSD3 |
Maintainer | ivan.perez@keera.co.uk |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
Synopsis
- data Event a
- class Arrow a => ArrowLoop (a :: Type -> Type -> Type) where
- loop :: a (b, d) (c, d) -> a b c
- newtype ArrowMonad (a :: Type -> Type -> Type) b = ArrowMonad (a () b)
- class Arrow a => ArrowApply (a :: Type -> Type -> Type) where
- app :: a (a b c, b) c
- class Arrow a => ArrowChoice (a :: Type -> Type -> Type) where
- class ArrowZero a => ArrowPlus (a :: Type -> Type -> Type) where
- (<+>) :: a b c -> a b c -> a b c
- class Arrow a => ArrowZero (a :: Type -> Type -> Type) where
- zeroArrow :: a b c
- newtype Kleisli (m :: Type -> Type) a b = Kleisli {
- runKleisli :: a -> m b
- class Category a => Arrow (a :: Type -> Type -> Type) where
- data MSF (m :: Type -> Type) a b
- type MSink (m :: Type -> Type) a = MSF m a ()
- type MStream (m :: Type -> Type) a = MSF m () a
- class VectorSpace v a | v -> a where
- zeroVector :: v
- (*^) :: a -> v -> v
- (^/) :: v -> a -> v
- (^+^) :: v -> v -> v
- (^-^) :: v -> v -> v
- negateVector :: v -> v
- dot :: v -> v -> a
- norm :: v -> a
- normalize :: v -> v
- type Time = Double
- type DTime = Double
- type ClockInfo m = ReaderT DTime m
- time :: Monad m => SF m a Time
- next :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b
- (-=>) :: Monad m => (b -> b) -> SF m a b -> SF m a b
- (>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c
- count :: forall n (m :: Type -> Type) a. (Num n, Monad m) => MSF m a n
- (<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c
- dup :: a -> (a, a)
- returnA :: Arrow a => a b b
- (^>>) :: Arrow a => (b -> c) -> a c d -> a b d
- (>>^) :: Arrow a => a b c -> (c -> d) -> a b d
- (<<^) :: Arrow a => a c d -> (b -> c) -> a b d
- (^<<) :: Arrow a => (c -> d) -> a b c -> a b d
- leftApp :: ArrowApply a => a b c -> a (Either b d) (Either c d)
- traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a
- unfold :: forall (m :: Type -> Type) a b. Monad m => (a -> (b, a)) -> a -> MSF m () b
- merge :: Event a -> Event a -> Event a
- morphGS :: Monad m2 => (forall c. (a1 -> m1 (b1, c)) -> a2 -> m2 (b2, c)) -> MSF m1 a1 b1 -> MSF m2 a2 b2
- feedback :: forall (m :: Type -> Type) c a b. Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b
- embed :: Monad m => MSF m a b -> [a] -> m [b]
- reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF Identity a b -> m ()
- constM :: Monad m => m b -> MSF m a b
- arrM :: Monad m => (a -> m b) -> MSF m a b
- liftBaseM :: forall (m2 :: Type -> Type) m1 a b. (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b
- liftBaseS :: forall (m2 :: Type -> Type) (m1 :: Type -> Type) a b. (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b
- (^>>>) :: 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
- (>>>^) :: 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
- 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
- morphS :: (Monad m2, Monad m1) => (forall c. m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b
- mapMaybeS :: forall (m :: Type -> Type) a b. Monad m => MSF m a b -> MSF m (Maybe a) (Maybe b)
- withSideEffect :: Monad m => (a -> m b) -> MSF m a a
- withSideEffect_ :: Monad m => m b -> MSF m a a
- iPre :: Monad m => a -> SF m a a
- iPost :: forall (m :: Type -> Type) b a. Monad m => b -> MSF m a b -> MSF m a b
- fifo :: forall (m :: Type -> Type) a. Monad m => MSF m [a] (Maybe a)
- sumS :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => MSF m v v
- sumFrom :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => v -> MSF m v v
- mappendS :: forall n (m :: Type -> Type). (Monoid n, Monad m) => MSF m n n
- mappendFrom :: forall n (m :: Type -> Type). (Monoid n, Monad m) => n -> MSF m n n
- accumulateWith :: forall (m :: Type -> Type) a s. Monad m => (a -> s -> s) -> s -> MSF m a s
- mealy :: forall (m :: Type -> Type) a s b. Monad m => (a -> s -> (b, s)) -> s -> MSF m a b
- repeatedly :: Monad m => Time -> b -> SF m a (Event b)
- traceWhen :: (Monad m, Show a) => (a -> Bool) -> (String -> m ()) -> String -> MSF m a a
- pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a
- once :: Monad m => SF m (Event a) (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
- eventToMaybe :: Event a -> Maybe a
- arr2 :: Arrow a => (b -> c -> d) -> a (b, c) d
- arr3 :: Arrow a => (b -> c -> d -> e) -> a (b, c, d) e
- arr4 :: Arrow a => (b -> c -> d -> e -> f) -> a (b, c, d, e) f
- arr5 :: Arrow a => (b -> c -> d -> e -> f -> g) -> a (b, c, d, e, f) g
- identity :: Monad m => SF m a a
- constant :: Monad m => b -> SF m a b
- (-->) :: Monad m => b -> SF m a b -> SF m a b
- (-:>) :: Monad m => b -> SF m a b -> SF m a b
- (>--) :: Monad m => a -> SF m a b -> SF m a b
- (>=-) :: Monad m => (a -> a) -> SF m a b -> SF m a b
- initially :: Monad m => a -> SF m a a
- provided :: Monad m => (a -> Bool) -> SF m a b -> SF m a b -> SF m a b
- pause :: Monad m => b -> SF m a Bool -> SF m a b -> SF m a b
- edge :: Monad m => SF m Bool (Event ())
- snap :: Monad m => SF m a (Event a)
- pre :: Monad m => SF m a a
- fby :: Monad m => b -> SF m a b -> SF m a b
- delay :: Monad m => Time -> a -> SF m a a
- sscanPrim :: Monad m => (c -> a -> Maybe (c, b)) -> c -> b -> SF m a b
- noEvent :: Event a
- noEventFst :: (Event a, b) -> (Event c, b)
- noEventSnd :: (a, Event b) -> (a, Event c)
- event :: a -> (b -> a) -> Event b -> a
- fromEvent :: Event a -> a
- isEvent :: Event a -> Bool
- isNoEvent :: Event a -> Bool
- tag :: Event a -> b -> Event b
- tagWith :: b -> Event a -> Event b
- attach :: Event a -> b -> Event (a, b)
- lMerge :: Event a -> Event a -> Event a
- rMerge :: Event a -> Event a -> Event a
- mergeBy :: (a -> a -> a) -> Event a -> Event a -> Event a
- mapMerge :: (a -> c) -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
- mergeEvents :: [Event a] -> Event a
- catEvents :: [Event a] -> Event [a]
- joinE :: Event a -> Event b -> Event (a, b)
- splitE :: Event (a, b) -> (Event a, Event b)
- filterE :: (a -> Bool) -> Event a -> Event a
- mapFilterE :: (a -> Maybe b) -> Event a -> Event b
- gate :: Event a -> Bool -> Event a
- maybeToEvent :: Maybe a -> Event a
- never :: Monad m => SF m a (Event b)
- now :: Monad m => b -> SF m a (Event b)
- after :: Monad m => Time -> b -> SF m a (Event b)
- afterEach :: Monad m => [(Time, b)] -> SF m a (Event b)
- afterEachCat :: Monad m => [(Time, b)] -> SF m a (Event [b])
- delayEvent :: Monad m => Time -> SF m (Event a) (Event a)
- delayEventCat :: Monad m => Time -> SF m (Event a) (Event [a])
- iEdge :: Monad m => Bool -> SF m Bool (Event ())
- edgeTag :: Monad m => a -> SF m Bool (Event a)
- edgeJust :: Monad m => SF m (Maybe a) (Event a)
- edgeBy :: Monad m => (a -> a -> Maybe b) -> a -> SF m a (Event b)
- notYet :: Monad m => SF m (Event a) (Event a)
- takeEvents :: Monad m => Int -> SF m (Event a) (Event a)
- dropEvents :: Monad m => Int -> SF m (Event a) (Event a)
- snapAfter :: Monad m => Time -> SF m a (Event a)
- sample :: Monad m => Time -> SF m a (Event a)
- sampleWindow :: Monad m => Int -> Time -> SF m a (Event [a])
- recur :: Monad m => SF m a (Event b) -> SF m a (Event b)
- andThen :: Monad m => SF m a (Event b) -> SF m a (Event b) -> SF m a (Event b)
- accumBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) (Event b)
- hold :: Monad m => a -> SF m (Event a) a
- integral :: (Monad m, Fractional s, VectorSpace a s) => SF m a a
- derivative :: (Monad m, Fractional s, VectorSpace a s) => SF m a a
- iterFrom :: Monad m => (a -> a -> DTime -> b -> b) -> b -> SF m a b
- sscan :: Monad m => (b -> a -> b) -> 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]
- localTime :: Monad m => SF m a Time
- mapEventS :: Monad m => SF m a b -> SF m (Event a) (Event b)
- accumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b
- boolToEvent :: Bool -> Event ()
- loopPre :: Monad m => c -> SF m (a, c) (b, c) -> SF m a b
- occasionally :: MonadRandom m => Time -> b -> SF m a (Event b)
- evalAtZero :: SF Identity a b -> a -> (b, SF Identity a b)
- evalAt :: SF Identity a b -> DTime -> a -> (b, SF Identity a b)
- evalFuture :: SF Identity a b -> a -> DTime -> (b, SF Identity a b)
- type SF = SF Identity
- type FutureSF = SF Identity
Documentation
A single possible event occurrence, that is, a value that may or may not occur. Events are used to represent values that are not produced continuously, such as mouse clicks (only produced when the mouse is clicked, as opposed to mouse positions, which are always defined).
Instances
MonadFail Event Source # | MonadFail instance |
Defined in FRP.BearRiver.Event | |
Alternative Event Source # | Alternative instance. |
Applicative Event Source # | Applicative instance (similar to |
Functor Event Source # | Functor instance (could be derived). |
Monad Event Source # | Monad instance. |
Show a => Show (Event a) Source # | |
NFData a => NFData (Event a) Source # | NFData instance. |
Defined in FRP.BearRiver.Event | |
Eq a => Eq (Event a) Source # | |
Ord a => Ord (Event a) Source # | |
class Arrow a => ArrowLoop (a :: Type -> Type -> Type) where #
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:
- extension
loop
(arr
f) =arr
(\ b ->fst
(fix
(\ (c,d) -> f (b,d))))- left tightening
loop
(first
h >>> f) = h >>>loop
f- right tightening
loop
(f >>>first
h) =loop
f >>> h- sliding
loop
(f >>>arr
(id
*** k)) =loop
(arr
(id
*** k) >>> f)- vanishing
loop
(loop
f) =loop
(arr
unassoc >>> f >>>arr
assoc)- superposing
second
(loop
f) =loop
(arr
assoc >>>second
f >>>arr
unassoc)
where
assoc ((a,b),c) = (a,(b,c)) unassoc (a,(b,c)) = ((a,b),c)
Instances
MonadFix m => ArrowLoop (Kleisli m) | Beware that for many monads (those for which the Since: base-2.1 |
Defined in Control.Arrow | |
ArrowLoop (->) | Since: base-2.1 |
Defined in Control.Arrow |
newtype ArrowMonad (a :: Type -> Type -> Type) b #
The ArrowApply
class is equivalent to Monad
: any monad gives rise
to a Kleisli
arrow, and any instance of ArrowApply
defines a monad.
ArrowMonad (a () b) |
Instances
class Arrow a => ArrowApply (a :: Type -> Type -> Type) where #
Some arrows allow application of arrow inputs to other inputs. Instances should satisfy the following laws:
first
(arr
(\x ->arr
(\y -> (x,y)))) >>>app
=id
first
(arr
(g >>>)) >>>app
=second
g >>>app
first
(arr
(>>> h)) >>>app
=app
>>> h
Such arrows are equivalent to monads (see ArrowMonad
).
Instances
Monad m => ArrowApply (Kleisli m) | Since: base-2.1 |
Defined in Control.Arrow | |
ArrowApply (->) | Since: base-2.1 |
Defined in Control.Arrow |
class Arrow a => ArrowChoice (a :: Type -> Type -> Type) where #
Choice, for arrows that support it. This class underlies the
if
and case
constructs in arrow notation.
Instances should satisfy the following laws:
left
(arr
f) =arr
(left
f)left
(f >>> g) =left
f >>>left
gf >>>
arr
Left
=arr
Left
>>>left
fleft
f >>>arr
(id
+++ g) =arr
(id
+++ g) >>>left
fleft
(left
f) >>>arr
assocsum =arr
assocsum >>>left
f
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.
left :: a b c -> a (Either b d) (Either c d) #
Feed marked inputs through the argument arrow, passing the rest through unchanged to the output.
right :: a b c -> a (Either d b) (Either d c) #
A mirror image of left
.
The default definition may be overridden with a more efficient version if desired.
(+++) :: a b c -> a b' c' -> a (Either b b') (Either c c') infixr 2 #
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.
(|||) :: a b d -> a c d -> a (Either b c) d infixr 2 #
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.
Instances
Monad m => ArrowChoice (Kleisli m) | Since: base-2.1 |
Defined in Control.Arrow | |
ArrowChoice (->) | Since: base-2.1 |
newtype Kleisli (m :: Type -> Type) a b #
Kleisli arrows of a monad.
Kleisli | |
|
Instances
Monad m => Category (Kleisli m :: Type -> Type -> Type) | Since: base-3.0 |
Generic1 (Kleisli m a :: Type -> Type) | |
Monad m => Arrow (Kleisli m) | Since: base-2.1 |
Monad m => ArrowApply (Kleisli m) | Since: base-2.1 |
Defined in Control.Arrow | |
Monad m => ArrowChoice (Kleisli m) | Since: base-2.1 |
Defined in Control.Arrow | |
MonadFix m => ArrowLoop (Kleisli m) | Beware that for many monads (those for which the Since: base-2.1 |
Defined in Control.Arrow | |
MonadPlus m => ArrowPlus (Kleisli m) | Since: base-2.1 |
MonadPlus m => ArrowZero (Kleisli m) | Since: base-2.1 |
Defined in Control.Arrow | |
Alternative m => Alternative (Kleisli m a) | Since: base-4.14.0.0 |
Applicative m => Applicative (Kleisli m a) | Since: base-4.14.0.0 |
Defined in Control.Arrow | |
Functor m => Functor (Kleisli m a) | Since: base-4.14.0.0 |
Monad m => Monad (Kleisli m a) | Since: base-4.14.0.0 |
MonadPlus m => MonadPlus (Kleisli m a) | Since: base-4.14.0.0 |
Generic (Kleisli m a b) | |
type Rep1 (Kleisli m a :: Type -> Type) | Since: base-4.14.0.0 |
type Rep (Kleisli m a b) | Since: base-4.14.0.0 |
Defined in Control.Arrow |
class Category a => Arrow (a :: Type -> Type -> Type) where #
The basic arrow class.
Instances should satisfy the following laws:
arr
id =id
arr
(f >>> g) =arr
f >>>arr
gfirst
(arr
f) =arr
(first
f)first
(f >>> g) =first
f >>>first
gfirst
f >>>arr
fst
=arr
fst
>>> ffirst
f >>>arr
(id
*** g) =arr
(id
*** g) >>>first
ffirst
(first
f) >>>arr
assoc =arr
assoc >>>first
f
where
assoc ((a,b),c) = (a,(b,c))
The other combinators have sensible default definitions, which may be overridden for efficiency.
Lift a function to an arrow.
first :: a b c -> a (b, d) (c, d) #
Send the first component of the input through the argument arrow, and copy the rest unchanged to the output.
second :: a b c -> a (d, b) (d, c) #
A mirror image of first
.
The default definition may be overridden with a more efficient version if desired.
(***) :: a b c -> a b' c' -> a (b, b') (c, c') infixr 3 #
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.
(&&&) :: a b c -> a b c' -> a b (c, c') infixr 3 #
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.
data MSF (m :: Type -> Type) a b #
Stepwise, side-effectful MSF
s without implicit knowledge of time.
MSF
s 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.
type MSink (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 MStream (m :: Type -> Type) a = MSF m () a #
A stream is an MSF
that produces outputs, while ignoring the input. It
can obtain the values from a monadic context.
class VectorSpace v a | v -> a where #
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.
zeroVector, (*^), (^+^), dot
zeroVector :: v #
Vector with no magnitude (unit for addition).
(*^) :: a -> v -> v infixr 9 #
Multiplication by a scalar.
(^/) :: v -> a -> v infixl 9 #
Division by a scalar.
(^+^) :: v -> v -> v infixl 6 #
Vector addition
(^-^) :: v -> v -> v infixl 6 #
Vector subtraction
negateVector :: v -> v #
Vector negation. Addition with a negated vector should be same as subtraction.
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.
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
.
Return a vector with the same origin and orientation (angle), but such that the norm is one (the unit for multiplication by a scalar).
Instances
VectorSpace Double Double | |
Defined in Data.VectorSpace | |
VectorSpace Float Float | |
Defined in Data.VectorSpace | |
(Eq a, Floating a) => VectorSpace (a, a) a | Vector space instance for pairs of |
Defined in Data.VectorSpace | |
(Eq a, Floating a) => VectorSpace (a, a, a) a | Vector space instance for triplets of |
Defined in Data.VectorSpace | |
(Eq a, Floating a) => VectorSpace (a, a, a, a) a | Vector space instance for tuples with four |
Defined in Data.VectorSpace zeroVector :: (a, a, a, a) # (*^) :: a -> (a, a, a, a) -> (a, a, a, a) # (^/) :: (a, a, a, a) -> a -> (a, a, a, a) # (^+^) :: (a, a, a, a) -> (a, a, a, a) -> (a, a, a, a) # (^-^) :: (a, a, a, a) -> (a, a, a, a) -> (a, a, a, a) # negateVector :: (a, a, a, a) -> (a, a, a, a) # | |
(Eq a, Floating a) => VectorSpace (a, a, a, a, a) a | Vector space instance for tuples with five |
Defined in Data.VectorSpace zeroVector :: (a, a, a, a, a) # (*^) :: a -> (a, a, a, a, a) -> (a, a, a, a, a) # (^/) :: (a, a, a, a, a) -> a -> (a, a, a, a, a) # (^+^) :: (a, a, a, a, a) -> (a, a, a, a, a) -> (a, a, a, a, a) # (^-^) :: (a, a, a, a, a) -> (a, a, a, a, a) -> (a, a, a, a, a) # negateVector :: (a, a, a, a, a) -> (a, a, a, a, a) # dot :: (a, a, a, a, a) -> (a, a, a, a, a) -> a # |
Time is used both for time intervals (duration), and time w.r.t. some agreed reference point in time.
DTime is the time type for lengths of sample intervals. Conceptually, DTime = R+ = { x in R | x > 0 }. Don't assume Time and DTime have the same representation.
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
, shifting the output.
(-=>) :: Monad m => (b -> b) -> SF m a b -> SF m a b infixr 0 Source #
Transform initial output value.
Applies a transformation f
only to the first output value at time zero.
(>>>) :: forall {k} cat (a :: k) (b :: k) (c :: k). Category cat => cat a b -> cat b c -> cat a c infixr 1 #
Left-to-right composition
count :: forall n (m :: Type -> Type) a. (Num n, Monad m) => MSF m a n #
Count the number of simulation steps. Produces 1, 2, 3,...
(<<<) :: forall {k} cat (b :: k) (c :: k) (a :: k). Category cat => cat b c -> cat a b -> cat a c infixr 1 #
Right-to-left composition
(<<^) :: Arrow a => a c d -> (b -> c) -> a b d infixr 1 #
Precomposition with a pure function (right-to-left variant).
(^<<) :: Arrow a => (c -> d) -> a b c -> a b d infixr 1 #
Postcomposition with a pure function (right-to-left variant).
leftApp :: ArrowApply a => a b c -> a (Either b d) (Either c d) #
Any instance of ArrowApply
can be made into an instance of
ArrowChoice
by defining left
= leftApp
.
traceWith :: (Monad m, Show a) => (String -> m ()) -> String -> MSF m a a #
Outputs every input sample, with a given message prefix, using an auxiliary printing function.
unfold :: forall (m :: Type -> Type) a b. Monad m => (a -> (b, a)) -> a -> MSF m () b #
Generate outputs using a step-wise generation function and an initial value.
merge :: Event a -> Event a -> Event a infixl 6 Source #
Unbiased event merge: simultaneous occurrence is an error.
:: Monad m2 | |
=> (forall c. (a1 -> m1 (b1, c)) -> a2 -> m2 (b2, c)) | The natural transformation. |
-> MSF m1 a1 b1 | |
-> MSF m2 a2 b2 |
Generic lifting of a morphism to the level of MSF
s.
Natural transformation to the level of MSF
s.
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.
feedback :: forall (m :: Type -> Type) c a b. Monad m => c -> MSF m (a, c) (b, c) -> MSF m a b #
Well-formed looped connection of an output component as a future input.
embed :: Monad m => MSF m a b -> [a] -> m [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"
reactimate :: Monad m => m a -> (Bool -> m (DTime, Maybe a)) -> (Bool -> b -> m Bool) -> SF Identity a b -> m () Source #
Convenience function to run a signal function indefinitely, using a IO actions to obtain new input and process the output.
This function first runs the initialization action, which provides the initial input for the signal transformer at time 0.
Afterwards, an input sensing action is used to obtain new input (if any) and the time since the last iteration. The argument to the input sensing function indicates if it can block. If no new input is received, it is assumed to be the same as in the last iteration.
After applying the signal function to the input, the actuation IO action is executed. The first argument indicates if the output has changed, the second gives the actual output). Actuation functions may choose to ignore the first argument altogether. This action should return True if the reactimation must stop, and False if it should continue.
Note that this becomes the program's main loop, which makes using this
function incompatible with GLUT, Gtk and other graphics libraries. It may
also impose a sizeable constraint in larger projects in which different
subparts run at different time steps. If you need to control the main loop
yourself for these or other reasons, use reactInit
and react
.
liftBaseM :: forall (m2 :: Type -> Type) m1 a b. (Monad m2, MonadBase m1 m2) => (a -> m1 b) -> MSF m2 a b #
Monadic lifting from one monad into another
liftBaseS :: forall (m2 :: Type -> Type) (m1 :: Type -> Type) a b. (Monad m2, MonadBase m1 m2) => MSF m1 a b -> MSF m2 a b #
Lift innermost monadic actions in monad stack (generalisation of
liftIO
).
(^>>>) :: 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 the first MSF
into the monad of the second.
(>>>^) :: 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 second MSF
into the monad of the first.
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 inner monadic actions in monad stacks.
morphS :: (Monad m2, Monad m1) => (forall c. m1 c -> m2 c) -> MSF m1 a b -> MSF m2 a b #
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.
withSideEffect :: Monad m => (a -> m b) -> MSF m a a #
Applies a function to produce an additional side effect and passes the input unchanged.
withSideEffect_ :: Monad m => m b -> MSF m a a #
Produces an additional side effect and passes the input unchanged.
iPre :: Monad m => a -> SF m a a Source #
Initialized delay operator.
Creates an SF that delays the input signal, introducing an infinitesimal delay (one sample), using the given argument to fill in the initial output at time zero.
iPost :: 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.
fifo :: forall (m :: Type -> Type) a. Monad m => MSF m [a] (Maybe a) #
Buffers and returns the elements in FIFO order, returning Nothing
whenever the buffer is empty.
sumS :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => MSF m v v #
Sums the inputs, starting from zero.
sumFrom :: forall v s (m :: Type -> Type). (VectorSpace v s, Monad m) => v -> MSF m v v #
Sums the inputs, starting from an initial vector.
mappendS :: forall n (m :: Type -> Type). (Monoid n, Monad m) => MSF m n n #
Accumulate the inputs, starting from mempty
.
mappendFrom :: forall n (m :: Type -> Type). (Monoid n, Monad m) => n -> MSF m n n #
Accumulate the inputs, starting from an initial monoid value.
accumulateWith :: forall (m :: Type -> Type) a s. Monad m => (a -> s -> s) -> s -> MSF m a s #
Applies a function to the input and an accumulator, outputting the updated
accumulator. Equal to f s0 -> feedback s0 $ arr (uncurry f >>> dup)
.
mealy :: forall (m :: Type -> Type) a s b. Monad m => (a -> s -> (b, s)) -> s -> MSF m a b #
Applies a transfer function to the input and an accumulator, returning the updated accumulator and output.
repeatedly :: Monad m => Time -> b -> SF m a (Event b) Source #
Event source with repeated occurrences with interval q.
Note: If the interval is too short w.r.t. the sampling intervals, the result will be that events occur at every sample. However, no more than one event results from any sampling interval, thus avoiding an "event backlog" should sampling become more frequent at some later point in time.
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, when a condition is met.
pauseOn :: Show a => (a -> Bool) -> String -> MSF IO a a #
Outputs every input sample, with a given message prefix, when a condition is met, and waits for some input / enter to continue.
switch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b Source #
Basic switch.
By default, the first signal function is applied. Whenever the second value in the pair actually is an event, the value carried by the event is used to obtain a new signal function to be applied *at that time and at future times*. Until that happens, the first value in the pair is produced in the output signal.
Important note: at the time of switching, the second signal function is applied immediately. If that second SF can also switch at time zero, then a double (nested) switch might take place. If the second SF refers to the first one, the switch might take place infinitely many times and never be resolved.
Remember: The continuation is evaluated strictly at the time of switching!
dSwitch :: Monad m => SF m a (b, Event c) -> (c -> SF m a b) -> SF m a b Source #
Switch with delayed observation.
By default, the first signal function is applied.
Whenever the second value in the pair actually is an event, the value carried by the event is used to obtain a new signal function to be applied *at future times*.
Until that happens, the first value in the pair is produced in the output signal.
Important note: at the time of switching, the second signal function is used immediately, but the current input is fed by it (even though the actual output signal value at time 0 is discarded).
If that second SF can also switch at time zero, then a double (nested) switch might take place. If the second SF refers to the first one, the switch might take place infinitely many times and never be resolved.
Remember: The continuation is evaluated strictly at the time of switching!
eventToMaybe :: Event a -> Maybe a Source #
Convert an Event
into a Maybe
value.
Both types are isomorphic, where a value containing an event is mapped to a
Just
, and NoEvent
is mapped to Nothing
. There is, however, a semantic
difference: a signal carrying a Maybe may change constantly, but, for a
signal carrying an Event
, there should be a bounded frequency such that
sampling the signal faster does not render more event occurrences.
arr4 :: Arrow a => (b -> c -> d -> e -> f) -> a (b, c, d, e) f Source #
Lift a 4-ary function onto an arrow.
arr5 :: Arrow a => (b -> c -> d -> e -> f -> g) -> a (b, c, d, e, f) g Source #
Lift a 5-ary function onto an arrow.
identity :: Monad m => SF m a a Source #
Identity: identity = arr id
Using identity
is preferred over lifting id, since the arrow combinators
know how to optimise certain networks based on the transformations being
applied.
constant :: Monad m => b -> SF m a b Source #
Identity: constant b = arr (const b)
Using constant
is preferred over lifting const, since the arrow combinators
know how to optimise certain networks based on the transformations being
applied.
(-->) :: Monad m => b -> SF m a b -> SF m a b infixr 0 Source #
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 Source #
Output pre-insert operator.
Insert a sample in the output, and from that point on, behave like the given sf.
(>--) :: Monad m => a -> SF m a b -> SF m a b infixr 0 Source #
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 -> a) -> SF m a b -> SF m a b infixr 0 Source #
Transform initial input value.
Applies a transformation f
only to the first input value at time zero.
provided :: Monad m => (a -> Bool) -> SF m a b -> SF m a b -> SF m a b Source #
Runs a signal function only when a given predicate is satisfied, otherwise runs the other signal function.
This is similar to ArrowChoice
, except that this resets the SFs after each
transition.
For example, the following integrates the incoming input numbers, using one integral if the numbers are even, and another if the input numbers are odd. Note how, every time we "switch", the old value of the integral is discarded.
>>>
embed (provided (even . round) integral integral) (deltaEncode 1 [1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2 :: Double])
[0.0,1.0,2.0,0.0,2.0,4.0,0.0,1.0,2.0,0.0,2.0,4.0]
pause :: Monad m => b -> SF m a Bool -> SF m a b -> SF m a b Source #
Given a value in an accumulator (b), a predicate signal function (sfC), and a second signal function (sf), pause will produce the accumulator b if sfC input is True, and will transform the signal using sf otherwise. It acts as a pause with an accumulator for the moments when the transformation is paused.
edge :: Monad m => SF m Bool (Event ()) Source #
A rising edge detector. Useful for things like detecting key presses. It is initialised as up, meaning that events occurring at time 0 will not be detected.
snap :: Monad m => SF m a (Event a) Source #
Event source with a single occurrence at time 0. The value of the event is obtained by sampling the input at that time.
pre :: Monad m => SF m a a Source #
Uninitialized delay operator.
The output has an infinitesimal delay (1 sample), and the value at time zero is undefined.
delay :: Monad m => Time -> a -> SF m a a Source #
Delay a signal by a fixed time t
, using the second parameter to fill in
the initial t
seconds.
sscanPrim :: Monad m => (c -> a -> Maybe (c, b)) -> c -> b -> SF m a b Source #
Generic version of sscan
, in which the auxiliary function produces an
internal accumulator and an "held" output.
Applies a function point-wise, using the last known Just
output to form the
output, and next input accumulator. If the output is Nothing
, the last
known accumulators are used. This creates a well-formed loop based on a pure,
auxiliary function.
Make the NoEvent constructor available. Useful e.g. for initialization, ((-->) & friends), and it's easily available anyway (e.g. mergeEvents []).
noEventFst :: (Event a, b) -> (Event c, b) Source #
Suppress any event in the first component of a pair.
noEventSnd :: (a, Event b) -> (a, Event c) Source #
Suppress any event in the second component of a pair.
tag :: Event a -> b -> Event b infixl 8 Source #
Tags an (occurring) event with a value ("replacing" the old value).
Applicative-based definition: tag = ($>)
tagWith :: b -> Event a -> Event b Source #
Tags an (occurring) event with a value ("replacing" the old value). Same as
tag
with the arguments swapped.
Applicative-based definition: tagWith = (<$)
attach :: Event a -> b -> Event (a, b) infixl 8 Source #
Attaches an extra value to the value of an occurring event.
lMerge :: Event a -> Event a -> Event a infixl 6 Source #
Left-biased event merge (always prefer left event, if present).
rMerge :: Event a -> Event a -> Event a infixl 6 Source #
Right-biased event merge (always prefer right event, if present).
:: (a -> c) | Mapping function used when first event is present. |
-> (b -> c) | Mapping function used when second event is present. |
-> (a -> b -> c) | Mapping function used when both events are present. |
-> Event a | First event |
-> Event b | Second event |
-> Event c |
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)
mergeEvents :: [Event a] -> Event a Source #
Merge a list of events; foremost event has priority.
Foldable-based definition: mergeEvents :: Foldable t => t (Event a) -> Event a mergeEvents = asum
catEvents :: [Event a] -> Event [a] Source #
Collect simultaneous event occurrences; no event if none.
joinE :: Event a -> Event b -> Event (a, b) infixl 7 Source #
Join (conjunction) of two events. Only produces an event if both events exist.
Applicative-based definition: joinE = liftA2 (,)
filterE :: (a -> Bool) -> Event a -> Event a Source #
Filter out events that don't satisfy some predicate.
gate :: Event a -> Bool -> Event a infixl 8 Source #
Enable/disable event occurrences based on an external condition.
maybeToEvent :: Maybe a -> Event a Source #
now :: Monad m => b -> SF m a (Event b) Source #
Event source with a single occurrence at time 0. The value of the event is given by the function argument.
:: Monad m | |
=> Time | The time q after which the event should be produced |
-> b | Value to produce at that time |
-> SF m a (Event b) |
Event source with a single occurrence at or as soon after (local) time q as possible.
afterEach :: Monad m => [(Time, b)] -> SF m a (Event b) Source #
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.
afterEachCat :: Monad m => [(Time, b)] -> SF m a (Event [b]) Source #
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.
delayEvent :: Monad m => Time -> SF m (Event a) (Event a) Source #
Delay for events. (Consider it a triggered after, hence basic.)
delayEventCat :: Monad m => Time -> SF m (Event a) (Event [a]) Source #
Delay an event by a given delta and catenate events that occur so closely so as to be inseparable.
edgeTag :: Monad m => a -> SF m Bool (Event a) Source #
Like edge
, but parameterized on the tag value.
edgeBy :: Monad m => (a -> a -> Maybe b) -> a -> SF m a (Event b) Source #
Edge detector parameterized on the edge detection function and initial state, i.e., the previous input sample. The first argument to the edge detection function is the previous sample, the second the current one.
notYet :: Monad m => SF m (Event a) (Event a) Source #
Suppression of initial (at local time 0) event.
takeEvents :: Monad m => Int -> SF m (Event a) (Event a) Source #
Suppress all but the first n events.
snapAfter :: Monad m => Time -> SF m a (Event a) Source #
Event source with a single occurrence at or as soon after (local) time
tEv
as possible. The value of the event is obtained by sampling the input a
that time.
sampleWindow :: Monad m => Int -> Time -> SF m a (Event [a]) Source #
Window sampling.
First argument is the window length wl, second is the sampling interval t. The output list should contain (min (truncate (T/t) wl)) samples, where T is the time the signal function has been running. This requires some care in case of sparse sampling. In case of sparse sampling, the current input value is assumed to have been present at all points where sampling was missed.
recur :: Monad m => SF m a (Event b) -> SF m a (Event b) Source #
Makes an event source recurring by restarting it as soon as it has an occurrence.
andThen :: Monad m => SF m a (Event b) -> SF m a (Event b) -> SF m a (Event b) Source #
Apply the first SF until it produces an event, and, afterwards, switch to the second SF. This is just a convenience function, used to write what sometimes is more understandable switch-based code.
accumBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) (Event b) Source #
Accumulator parameterized by the accumulation function.
hold :: Monad m => a -> SF m (Event a) a Source #
Zero-order hold.
Converts a discrete-time signal into a continuous-time signal, by holding the last value until it changes in the input signal. The given parameter may be used for time zero, and until the first event occurs in the input signal, so hold is always well-initialized.
>>>
embed (hold 1) (deltaEncode 0.1 [NoEvent, NoEvent, Event 2, NoEvent, Event 3, NoEvent])
[1,1,2,2,3,3]
integral :: (Monad m, Fractional s, VectorSpace a s) => SF m a a Source #
Integration using the rectangle rule.
derivative :: (Monad m, Fractional s, VectorSpace a s) => SF m a a Source #
A very crude version of a derivative. It simply divides the value difference by the time difference. Use at your own risk.
iterFrom :: Monad m => (a -> a -> DTime -> b -> b) -> b -> SF m a b Source #
Integrate using an auxiliary function that takes the current and the last input, the time between those samples, and the last output, and returns a new output.
sscan :: Monad m => (b -> a -> b) -> b -> SF m a b Source #
Applies a function point-wise, using the last output as next input. This creates a well-formed loop based on a pure, auxiliary function.
parB :: Monad m => [SF m a b] -> SF m a [b] Source #
Spatial parallel composition of a signal function collection. Given a
collection of signal functions, it returns a signal function that broadcasts
its input signal to every element of the collection, to return a signal
carrying a collection of outputs. See par
.
For more information on how parallel composition works, check https://www.antonycourtney.com/pubs/hw03.pdf
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) Source #
Decoupled parallel switch with broadcasting (dynamic collection of signal
functions spatially composed in parallel). See dpSwitch
.
For more information on how parallel composition works, check https://www.antonycourtney.com/pubs/hw03.pdf
parC :: Monad m => SF m a b -> SF m [a] [b] Source #
Apply an SF to every element of a list.
Example:
>>>
embed (parC integral) (deltaEncode 0.1 [[1, 2], [2, 4], [3, 6], [4.0, 8.0 :: Float]])
[[0.0,0.0],[0.1,0.2],[0.3,0.6],[0.6,1.2]]
The number of SFs or expected inputs is determined by the first input list, and not expected to vary over time.
If more inputs come in a subsequent list, they are ignored.
>>>
embed (parC (arr (+1))) (deltaEncode 0.1 [[0], [1, 1], [3, 4], [6, 7, 8], [1, 1], [0, 0], [1, 9, 8]])
[[1],[2],[4],[7],[2],[1],[2]]
If less inputs come in a subsequent list, an exception is thrown.
>>>
embed (parC (arr (+1))) (deltaEncode 0.1 [[0, 0], [1, 1], [3, 4], [6, 7, 8], [1, 1], [0, 0], [1, 9, 8]])
[[1,1],[2,2],[4,5],[7,8],[2,2],[1,1],[2,10]]
localTime :: Monad m => SF m a Time Source #
Outputs the time passed since the signal function instance was started.
accumHoldBy :: Monad m => (b -> a -> b) -> b -> SF m (Event a) b Source #
Zero-order hold accumulator parameterized by the accumulation function.
loopPre :: Monad m => c -> SF m (a, c) (b, c) -> SF m a b Source #
Loop with an initial value for the signal being fed back.
:: MonadRandom m | |
=> Time | The time q after which the event should be produced on average |
-> b | Value to produce at time of event |
-> SF m a (Event b) |
Stochastic event source with events occurring on average once every tAvg seconds. However, no more than one event results from any one sampling interval in the case of relatively sparse sampling, thus avoiding an "event backlog" should sampling become more frequent at some later point in time.
evalAtZero :: SF Identity a b -> a -> (b, SF Identity a b) Source #
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.
evalAt :: SF Identity a b -> DTime -> a -> (b, SF Identity a b) Source #
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.
evalFuture :: SF Identity a b -> a -> DTime -> (b, SF Identity a b) Source #
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.