    {-----------------------------------------------------------------------------
        reactive-banana
    ------------------------------------------------------------------------------}
    {-# LANGUAGE Rank2Types #-}
    {-# LANGUAGE RecursiveDo #-}
    {-# LANGUAGE MultiParamTypeClasses #-}

    module Reactive.Banana.Combinators (
        -- * Synopsis
        -- $synopsis

        -- * Core Combinators
        -- ** Event and Behavior
        Event, Behavior,
        interpret,

        -- ** First-order
        -- | This subsections lists the primitive first-order combinators for FRP.
        -- The 'Functor', 'Applicative' and 'Monoid' instances are also part of this,
        -- but they are documented at the types 'Event' and 'Behavior'.
        module Control.Applicative,
        module Data.Semigroup,
        never, unionWith, filterE,
        apply,

        -- ** Moment and accumulation
        Moment, MonadMoment(..),
        accumE, stepper,

        -- ** Recursion
        -- $recursion

        -- ** Higher-order
        valueB, valueBLater, observeE, switchE, switchB,

        -- * Derived Combinators
        -- ** Infix operators
        (<@>), (<@), (@>),
        -- ** Filtering
        filterJust, filterApply, whenE, split, once,
        -- ** Accumulation
        -- $Accumulation.
        unions, accumB, mapAccum,
        -- ** Merging events
        merge, mergeWith
        ) where

    import Control.Applicative
    import Data.Semigroup
    import Data.These (These(..))

    import qualified Reactive.Banana.Prim.High.Combinators as Prim
    import           Reactive.Banana.Types

    {-----------------------------------------------------------------------------
        Introduction
    ------------------------------------------------------------------------------}
    {-$synopsis

    The main types and combinators of Functional Reactive Programming (FRP).

    At its core, FRP is about two data types 'Event' and 'Behavior'
    and the various ways to combine them.
    There is also a third type 'Moment',
    which is necessary for the higher-order combinators.

    -}

    -- Event
    -- Behavior

    {-----------------------------------------------------------------------------
        Interpetation
    ------------------------------------------------------------------------------}
    -- | Interpret an event processing function.
    -- Useful for testing.
    --
    -- Note: You can safely assume that this function is pure,
    -- even though the type seems to suggest otherwise.
    -- I'm really sorry about the extra 'IO', but it can't be helped.
    -- See source code for the sordid details.
    interpret :: (Event a -> Moment (Event b)) -> [Maybe a] -> IO [Maybe b]
    interpret :: forall a b.
    (Event a -> Moment (Event b)) -> [Maybe a] -> IO [Maybe b]
    interpret Event a -> Moment (Event b)
    f [Maybe a]
    xs = (Event a -> Moment (Event b)) -> [Maybe a] -> IO [Maybe b]
    forall a b.
    (Event a -> Moment (Event b)) -> [Maybe a] -> IO [Maybe b]
    Prim.interpret ((Event b -> Event b)
    -> ReaderT EventNetwork Build (Event b) -> Moment (Event b)
    forall a b.
    (a -> b)
    -> ReaderT EventNetwork Build a -> ReaderT EventNetwork Build b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Event b -> Event b
    forall a. Event a -> Event a
    unE (ReaderT EventNetwork Build (Event b) -> Moment (Event b))
    -> (Event a -> ReaderT EventNetwork Build (Event b))
    -> Event a
    -> Moment (Event b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment (Event b) -> ReaderT EventNetwork Build (Event b)
    forall a. Moment a -> Moment a
    unM (Moment (Event b) -> ReaderT EventNetwork Build (Event b))
    -> (Event a -> Moment (Event b))
    -> Event a
    -> ReaderT EventNetwork Build (Event b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event a -> Moment (Event b)
    f (Event a -> Moment (Event b))
    -> (Event a -> Event a) -> Event a -> Moment (Event b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event a -> Event a
    forall a. Event a -> Event a
    E) [Maybe a]
    xs
    -- FIXME: I would love to remove the 'IO' from the type signature,
    -- but unfortunately, it is possible that the argument to interpret
    -- returns an Event that was created in the context of an existing network, e.g.
    --
    -- >   eBad <- fromAddHandler ...
    -- >   ...
    -- >   let ys = interpret (\_ -> return eBad ) xs
    --
    -- Doing this is a big no-no and will break a lot of things,
    -- but if we remove the 'IO' here, then we will also break referential
    -- transparency, and I think that takes it too far.

    {-----------------------------------------------------------------------------
        Core combinators
    ------------------------------------------------------------------------------}
    -- | Event that never occurs.
    -- Semantically,
    --
    -- > never = []
    never    :: Event a
    never :: forall a. Event a
    never = Event a -> Event a
    forall a. Event a -> Event a
    E Event a
    forall a. Event a
    Prim.never

    -- | Merge two event streams of the same type.
    -- The function argument specifies how event values are to be combined
    -- in case of a simultaneous occurrence. The semantics are
    --
    -- > unionWith f ((timex,x):xs) ((timey,y):ys)
    -- >    | timex <  timey = (timex,x)     : unionWith f xs ((timey,y):ys)
    -- >    | timex >  timey = (timey,y)     : unionWith f ((timex,x):xs) ys
    -- >    | timex == timey = (timex,f x y) : unionWith f xs ys
    unionWith :: (a -> a -> a) -> Event a -> Event a -> Event a
    unionWith :: forall a. (a -> a -> a) -> Event a -> Event a -> Event a
    unionWith a -> a -> a
    f = (a -> a)
    -> (a -> a) -> (a -> a -> a) -> Event a -> Event a -> Event a
    forall a c b.
    (a -> c)
    -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
    mergeWith a -> a
    forall a. a -> a
    id a -> a
    forall a. a -> a
    id a -> a -> a
    f

    -- | Merge two event streams of any type.
    merge :: Event a -> Event b -> Event (These a b)
    merge :: forall a b. Event a -> Event b -> Event (These a b)
    merge = (a -> These a b)
    -> (b -> These a b)
    -> (a -> b -> These a b)
    -> Event a
    -> Event b
    -> Event (These a b)
    forall a c b.
    (a -> c)
    -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
    mergeWith a -> These a b
    forall a b. a -> These a b
    This b -> These a b
    forall a b. b -> These a b
    That a -> b -> These a b
    forall a b. a -> b -> These a b
    These

    -- | Merge two event streams of any type.
    --
    -- This function generalizes 'unionWith'.
    mergeWith
      :: (a -> c) -- ^ The function called when only the first event emits a value.
      -> (b -> c) -- ^ The function called when only the second event emits a value.
      -> (a -> b -> c) -- ^ The function called when both events emit values simultaneously.
      -> Event a
      -> Event b
      -> Event c
    mergeWith :: forall a c b.
    (a -> c)
    -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
    mergeWith a -> c
    f b -> c
    g a -> b -> c
    h Event a
    e1 Event b
    e2 = Event c -> Event c
    forall a. Event a -> Event a
    E (Event c -> Event c) -> Event c -> Event c
    forall a b. (a -> b) -> a -> b
    $ (a -> c)
    -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
    forall a c b.
    (a -> c)
    -> (b -> c) -> (a -> b -> c) -> Event a -> Event b -> Event c
    Prim.mergeWith a -> c
    f b -> c
    g a -> b -> c
    h (Event a -> Event a
    forall a. Event a -> Event a
    unE Event a
    e1) (Event b -> Event b
    forall a. Event a -> Event a
    unE Event b
    e2)

    -- | Allow all event occurrences that are 'Just' values, discard the rest.
    -- Variant of 'filterE'.
    filterJust :: Event (Maybe a) -> Event a
    filterJust :: forall a. Event (Maybe a) -> Event a
    filterJust = Event a -> Event a
    forall a. Event a -> Event a
    E (Event a -> Event a)
    -> (Event (Maybe a) -> Event a) -> Event (Maybe a) -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (Maybe a) -> Event a
    forall a. Event (Maybe a) -> Event a
    Prim.filterJust (Event (Maybe a) -> Event a)
    -> (Event (Maybe a) -> Event (Maybe a))
    -> Event (Maybe a)
    -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (Maybe a) -> Event (Maybe a)
    forall a. Event a -> Event a
    unE

    -- | Allow all events that fulfill the predicate, discard the rest.
    -- Semantically,
    --
    -- > filterE p es = [(time,a) | (time,a) <- es, p a]
    filterE   :: (a -> Bool) -> Event a -> Event a
    filterE :: forall a. (a -> Bool) -> Event a -> Event a
    filterE a -> Bool
    p = Event (Maybe a) -> Event a
    forall a. Event (Maybe a) -> Event a
    filterJust (Event (Maybe a) -> Event a)
    -> (Event a -> Event (Maybe a)) -> Event a -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (a -> Maybe a) -> Event a -> Event (Maybe a)
    forall a b. (a -> b) -> Event a -> Event b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (\a
    x -> if a -> Bool
    p a
    x then a -> Maybe a
    forall a. a -> Maybe a
    Just a
    x else Maybe a
    forall a. Maybe a
    Nothing)

    -- | Apply a time-varying function to a stream of events.
    -- Semantically,
    --
    -- > apply bf ex = [(time, bf time x) | (time, x) <- ex]
    --
    -- This function is generally used in its infix variant '<@>'.
    apply :: Behavior (a -> b) -> Event a -> Event b
    apply :: forall a b. Behavior (a -> b) -> Event a -> Event b
    apply Behavior (a -> b)
    bf Event a
    ex = Event b -> Event b
    forall a. Event a -> Event a
    E (Event b -> Event b) -> Event b -> Event b
    forall a b. (a -> b) -> a -> b
    $ Behavior (a -> b) -> Event a -> Event b
    forall a b. Behavior (a -> b) -> Event a -> Event b
    Prim.applyE (Behavior (a -> b) -> Behavior (a -> b)
    forall a. Behavior a -> Behavior a
    unB Behavior (a -> b)
    bf) (Event a -> Event a
    forall a. Event a -> Event a
    unE Event a
    ex)

    -- | Construct a time-varying function from an initial value and
    -- a stream of new values. The result will be a step function.
    -- Semantically,
    --
    -- > stepper x0 ex = \time1 -> \time2 ->
    -- >     last (x0 : [x | (timex,x) <- ex, time1 <= timex, timex < time2])
    --
    -- Here is an illustration of the result Behavior at a particular time:
    --
    -- <<doc/frp-stepper.png>>
    --
    -- Note: The smaller-than-sign in the comparison @timex < time2@ means
    -- that at time @time2 == timex@, the value of the Behavior will
    -- still be the previous value.
    -- In the illustration, this is indicated by the dots at the end
    -- of each step.
    -- This allows for recursive definitions.
    -- See the discussion below for more on recursion.
    stepper :: MonadMoment m => a -> Event a -> m (Behavior a)
    stepper :: forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event a -> m (Behavior a)
    stepper a
    a = Moment (Behavior a) -> m (Behavior a)
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment (Behavior a) -> m (Behavior a))
    -> (Event a -> Moment (Behavior a)) -> Event a -> m (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment (Behavior a) -> Moment (Behavior a)
    forall a. Moment a -> Moment a
    M (Moment (Behavior a) -> Moment (Behavior a))
    -> (Event a -> Moment (Behavior a))
    -> Event a
    -> Moment (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Behavior a -> Behavior a)
    -> ReaderT EventNetwork Build (Behavior a) -> Moment (Behavior a)
    forall a b.
    (a -> b)
    -> ReaderT EventNetwork Build a -> ReaderT EventNetwork Build b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    B (ReaderT EventNetwork Build (Behavior a) -> Moment (Behavior a))
    -> (Event a -> ReaderT EventNetwork Build (Behavior a))
    -> Event a
    -> Moment (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Event a -> ReaderT EventNetwork Build (Behavior a)
    forall a. a -> Event a -> Moment (Behavior a)
    Prim.stepperB a
    a (Event a -> ReaderT EventNetwork Build (Behavior a))
    -> (Event a -> Event a)
    -> Event a
    -> ReaderT EventNetwork Build (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event a -> Event a
    forall a. Event a -> Event a
    unE

    -- | The 'accumE' function accumulates a stream of event values,
    -- similar to a /strict/ left scan, 'scanl''.
    -- It starts with an initial value and emits a new value
    -- whenever an event occurrence happens.
    -- The new value is calculated by applying the function in the event
    -- to the old value.
    --
    -- Example:
    --
    -- > accumE "x" [(time1,(++"y")),(time2,(++"z"))]
    -- >     = trimE [(time1,"xy"),(time2,"xyz")]
    -- >     where
    -- >     trimE e start = [(time,x) | (time,x) <- e, start <= time]
    accumE :: MonadMoment m => a -> Event (a -> a) -> m (Event a)
    accumE :: forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event (a -> a) -> m (Event a)
    accumE a
    acc = Moment (Event a) -> m (Event a)
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment (Event a) -> m (Event a))
    -> (Event (a -> a) -> Moment (Event a))
    -> Event (a -> a)
    -> m (Event a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment (Event a) -> Moment (Event a)
    forall a. Moment a -> Moment a
    M (Moment (Event a) -> Moment (Event a))
    -> (Event (a -> a) -> Moment (Event a))
    -> Event (a -> a)
    -> Moment (Event a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Event a -> Event a)
    -> ReaderT EventNetwork Build (Event a) -> Moment (Event a)
    forall a b.
    (a -> b)
    -> ReaderT EventNetwork Build a -> ReaderT EventNetwork Build b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Event a -> Event a
    forall a. Event a -> Event a
    E (ReaderT EventNetwork Build (Event a) -> Moment (Event a))
    -> (Event (a -> a) -> ReaderT EventNetwork Build (Event a))
    -> Event (a -> a)
    -> Moment (Event a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Event (a -> a) -> ReaderT EventNetwork Build (Event a)
    forall a. a -> Event (a -> a) -> Moment (Event a)
    Prim.accumE a
    acc (Event (a -> a) -> ReaderT EventNetwork Build (Event a))
    -> (Event (a -> a) -> Event (a -> a))
    -> Event (a -> a)
    -> ReaderT EventNetwork Build (Event a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (a -> a) -> Event (a -> a)
    forall a. Event a -> Event a
    unE

    {-$recursion

    /Recursion/ is a very important technique in FRP that is not apparent
    from the type signatures.

    Here is a prototypical example. It shows how the 'accumE' can be expressed
    in terms of the 'stepper' and 'apply' functions by using recursion:

    > accumE a e1 = mdo
    >    let e2 = (\a f -> f a) <$> b <@> e1
    >    b <- stepper a e2
    >    return e2

    (The @mdo@ notation refers to /value recursion/ in a monad.
    The 'MonadFix' instance for the 'Moment' class enables this kind of recursive code.)
    (Strictly speaking, this also means that 'accumE' is not a primitive,
    because it can be expressed in terms of other combinators.)

    This general pattern appears very often in practice:
    A Behavior (here @b@) controls what value is put into an Event (here @e2@),
    but at the same time, the Event contributes to changes in this Behavior.
    Modeling this situation requires recursion.

    For another example, consider a vending machine that sells banana juice.
    The amount that the customer still has to pay for a juice
    is modeled by a Behavior @bAmount@.
    Whenever the customer inserts a coin into the machine,
    an Event @eCoin@ occurs, and the amount will be reduced.
    Whenver the amount goes below zero, an Event @eSold@ will occur,
    indicating the release of a bottle of fresh banana juice,
    and the amount to be paid will be reset to the original price.
    The model requires recursion, and can be expressed in code as follows:

    > mdo
    >     let price = 50 :: Int
    >     bAmount  <- accumB price $ unions
    >                   [ subtract 10 <$ eCoin
    >                   , const price <$ eSold ]
    >     let eSold = whenE ((<= 0) <$> bAmount) eCoin

    On one hand, the Behavior @bAmount@ controls whether the Event @eSold@
    occcurs at all; the bottle of banana juice is unavailable to penniless customers.
    But at the same time, the Event @eSold@ will cause a reset
    of the Behavior @bAmount@, so both depend on each other.

    Recursive code like this examples works thanks to the semantics of 'stepper'.
    In general, /mutual recursion/ between several 'Event's and 'Behavior's
    is always well-defined,
    as long as an Event depends on itself only /via/ a Behavior,
    and vice versa.

    -}

    -- | Obtain the value of the 'Behavior' at a given moment in time.
    -- Semantically, it corresponds to
    --
    -- > valueB b = \time -> b time
    --
    -- Note: The value is immediately available for pattern matching.
    -- Unfortunately, this means that @valueB@ is unsuitable for use
    -- with value recursion in the 'Moment' monad.
    -- If you need recursion, please use 'valueBLater' instead.
    valueB :: MonadMoment m => Behavior a -> m a
    valueB :: forall (m :: * -> *) a. MonadMoment m => Behavior a -> m a
    valueB = Moment a -> m a
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment a -> m a) -> (Behavior a -> Moment a) -> Behavior a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment a -> Moment a
    forall a. Moment a -> Moment a
    M (Moment a -> Moment a)
    -> (Behavior a -> Moment a) -> Behavior a -> Moment a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior a -> Moment a
    forall a. Behavior a -> Moment a
    Prim.valueB (Behavior a -> Moment a)
    -> (Behavior a -> Behavior a) -> Behavior a -> Moment a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    unB

    -- | Obtain the value of the 'Behavior' at a given moment in time.
    -- Semantically, it corresponds to
    --
    -- > valueBLater b = \time -> b time
    --
    -- Note: To allow for more recursion, the value is returned /lazily/
    -- and not available for pattern matching immediately.
    -- It can be used safely with most combinators like 'stepper'.
    -- If that doesn't work for you, please use 'valueB' instead.
    valueBLater :: MonadMoment m => Behavior a -> m a
    valueBLater :: forall (m :: * -> *) a. MonadMoment m => Behavior a -> m a
    valueBLater = Moment a -> m a
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment a -> m a) -> (Behavior a -> Moment a) -> Behavior a -> m a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment a -> Moment a
    forall a. Moment a -> Moment a
    M (Moment a -> Moment a)
    -> (Behavior a -> Moment a) -> Behavior a -> Moment a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior a -> Moment a
    forall a. Behavior a -> Moment a
    Prim.initialBLater (Behavior a -> Moment a)
    -> (Behavior a -> Behavior a) -> Behavior a -> Moment a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    unB

    -- | Observe a value at those moments in time where
    -- event occurrences happen. Semantically,
    --
    -- > observeE e = [(time, m time) | (time, m) <- e]
    observeE :: Event (Moment a) -> Event a
    observeE :: forall a. Event (Moment a) -> Event a
    observeE = Event a -> Event a
    forall a. Event a -> Event a
    E (Event a -> Event a)
    -> (Event (Moment a) -> Event a) -> Event (Moment a) -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (Moment a) -> Event a
    forall a. Event (Moment a) -> Event a
    Prim.observeE (Event (Moment a) -> Event a)
    -> (Event (Moment a) -> Event (Moment a))
    -> Event (Moment a)
    -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Moment a -> Moment a) -> Event (Moment a) -> Event (Moment a)
    forall a b. (a -> b) -> Event a -> Event b
    Prim.mapE Moment a -> Moment a
    forall a. Moment a -> Moment a
    unM (Event (Moment a) -> Event (Moment a))
    -> (Event (Moment a) -> Event (Moment a))
    -> Event (Moment a)
    -> Event (Moment a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (Moment a) -> Event (Moment a)
    forall a. Event a -> Event a
    unE

    -- | Dynamically switch between 'Event'.
    -- Semantically,
    --
    -- > switchE e0 ee0 time0 =
    -- >     concat [ trim t1 t2 e | (t1,t2,e) <- intervals ee ]
    -- >   where
    -- >     laterThan e time0  = [(timex,x) | (timex,x) <- e, time0 < timex ]
    -- >     ee                 = [(time0, e0)] ++ (ee0 `laterThan` time0)
    -- >     intervals ee       = [(time1, time2, e) | ((time1,e),(time2,_)) <- zip ee (tail ee)]
    -- >     trim time1 time2 e = [x | (timex,x) <- e, time1 < timex, timex <= time2]
    switchE :: MonadMoment m => Event a -> Event (Event a) -> m (Event a)
    switchE :: forall (m :: * -> *) a.
    MonadMoment m =>
    Event a -> Event (Event a) -> m (Event a)
    switchE Event a
    e Event (Event a)
    ee = Moment (Event a) -> m (Event a)
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment (Event a) -> Moment (Event a)
    forall a. Moment a -> Moment a
    M ((Event a -> Event a)
    -> ReaderT EventNetwork Build (Event a) -> Moment (Event a)
    forall a b.
    (a -> b)
    -> ReaderT EventNetwork Build a -> ReaderT EventNetwork Build b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Event a -> Event a
    forall a. Event a -> Event a
    E (Event a -> Event (Event a) -> ReaderT EventNetwork Build (Event a)
    forall a. Event a -> Event (Event a) -> Moment (Event a)
    Prim.switchE (Event a -> Event a
    forall a. Event a -> Event a
    unE Event a
    e) ((Event a -> Event a) -> Event (Event a) -> Event (Event a)
    forall a b. (a -> b) -> Event a -> Event b
    Prim.mapE Event a -> Event a
    forall a. Event a -> Event a
    unE (Event (Event a) -> Event (Event a)
    forall a. Event a -> Event a
    unE Event (Event a)
    ee)))))

    -- | Dynamically switch between 'Behavior'.
    -- Semantically,
    --
    -- >  switchB b0 eb = \time0 -> \time1 ->
    -- >     last (b0 : [b | (timeb,b) <- eb, time0 <= timeb, timeb < time1]) time1
    switchB :: MonadMoment m => Behavior a -> Event (Behavior a) -> m (Behavior a)
    switchB :: forall (m :: * -> *) a.
    MonadMoment m =>
    Behavior a -> Event (Behavior a) -> m (Behavior a)
    switchB Behavior a
    b = Moment (Behavior a) -> m (Behavior a)
    forall a. Moment a -> m a
    forall (m :: * -> *) a. MonadMoment m => Moment a -> m a
    liftMoment (Moment (Behavior a) -> m (Behavior a))
    -> (Event (Behavior a) -> Moment (Behavior a))
    -> Event (Behavior a)
    -> m (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Moment (Behavior a) -> Moment (Behavior a)
    forall a. Moment a -> Moment a
    M (Moment (Behavior a) -> Moment (Behavior a))
    -> (Event (Behavior a) -> Moment (Behavior a))
    -> Event (Behavior a)
    -> Moment (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Behavior a -> Behavior a)
    -> ReaderT EventNetwork Build (Behavior a) -> Moment (Behavior a)
    forall a b.
    (a -> b)
    -> ReaderT EventNetwork Build a -> ReaderT EventNetwork Build b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    B (ReaderT EventNetwork Build (Behavior a) -> Moment (Behavior a))
    -> (Event (Behavior a) -> ReaderT EventNetwork Build (Behavior a))
    -> Event (Behavior a)
    -> Moment (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior a
    -> Event (Behavior a) -> ReaderT EventNetwork Build (Behavior a)
    forall a. Behavior a -> Event (Behavior a) -> Moment (Behavior a)
    Prim.switchB (Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    unB Behavior a
    b) (Event (Behavior a) -> ReaderT EventNetwork Build (Behavior a))
    -> (Event (Behavior a) -> Event (Behavior a))
    -> Event (Behavior a)
    -> ReaderT EventNetwork Build (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Behavior a -> Behavior a)
    -> Event (Behavior a) -> Event (Behavior a)
    forall a b. (a -> b) -> Event a -> Event b
    Prim.mapE Behavior a -> Behavior a
    forall a. Behavior a -> Behavior a
    unB (Event (Behavior a) -> Event (Behavior a))
    -> (Event (Behavior a) -> Event (Behavior a))
    -> Event (Behavior a)
    -> Event (Behavior a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Event (Behavior a) -> Event (Behavior a)
    forall a. Event a -> Event a
    unE

    {-----------------------------------------------------------------------------
        Derived Combinators
    ------------------------------------------------------------------------------}
    infixl 4 <@>, <@, @>

    -- | Infix synonym for the 'apply' combinator. Similar to '<*>'.
    --
    -- > infixl 4 <@>
    (<@>) :: Behavior (a -> b) -> Event a -> Event b
    <@> :: forall a b. Behavior (a -> b) -> Event a -> Event b
    (<@>) = Behavior (a -> b) -> Event a -> Event b
    forall a b. Behavior (a -> b) -> Event a -> Event b
    apply

    -- | Tag all event occurrences with a time-varying value. Similar to '<*'.
    --
    -- > infixl 4 <@
    (<@)  :: Behavior b -> Event a -> Event b
    Behavior b
    f <@ :: forall b a. Behavior b -> Event a -> Event b
    <@ Event a
    g = (b -> a -> b
    forall a b. a -> b -> a
    const (b -> a -> b) -> Behavior b -> Behavior (a -> b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Behavior b
    f) Behavior (a -> b) -> Event a -> Event b
    forall a b. Behavior (a -> b) -> Event a -> Event b
    <@> Event a
    g

    -- | Tag all event occurences with a time-varying value. Similar to '*>'.
    --
    -- This is the flipped version of '<@', but can be useful when combined with
    -- @ApplicativeDo@ to sample from multiple 'Behavior's:
    --
    -- @
    -- reactimate $ onEvent @> do
    --   x <- behavior1
    --   y <- behavior2
    --   return (print (x + y))
    -- @
    (@>) :: Event a -> Behavior b -> Event b
    Event a
    g @> :: forall a b. Event a -> Behavior b -> Event b
    @> Behavior b
    f = (b -> a -> b
    forall a b. a -> b -> a
    const (b -> a -> b) -> Behavior b -> Behavior (a -> b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Behavior b
    f) Behavior (a -> b) -> Event a -> Event b
    forall a b. Behavior (a -> b) -> Event a -> Event b
    <@> Event a
    g

    -- | Allow all events that fulfill the time-varying predicate, discard the rest.
    -- Generalization of 'filterE'.
    filterApply :: Behavior (a -> Bool) -> Event a -> Event a
    filterApply :: forall a. Behavior (a -> Bool) -> Event a -> Event a
    filterApply Behavior (a -> Bool)
    bp = ((Bool, a) -> a) -> Event (Bool, a) -> Event a
    forall a b. (a -> b) -> Event a -> Event b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap (Bool, a) -> a
    forall a b. (a, b) -> b
    snd (Event (Bool, a) -> Event a)
    -> (Event a -> Event (Bool, a)) -> Event a -> Event a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ((Bool, a) -> Bool) -> Event (Bool, a) -> Event (Bool, a)
    forall a. (a -> Bool) -> Event a -> Event a
    filterE (Bool, a) -> Bool
    forall a b. (a, b) -> a
    fst (Event (Bool, a) -> Event (Bool, a))
    -> (Event a -> Event (Bool, a)) -> Event a -> Event (Bool, a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Behavior (a -> (Bool, a)) -> Event a -> Event (Bool, a)
    forall a b. Behavior (a -> b) -> Event a -> Event b
    apply ((\a -> Bool
    p a
    a-> (a -> Bool
    p a
    a,a
    a)) ((a -> Bool) -> a -> (Bool, a))
    -> Behavior (a -> Bool) -> Behavior (a -> (Bool, a))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Behavior (a -> Bool)
    bp)

    -- | Allow events only when the behavior is 'True'.
    -- Variant of 'filterApply'.
    whenE :: Behavior Bool -> Event a -> Event a
    whenE :: forall a. Behavior Bool -> Event a -> Event a
    whenE Behavior Bool
    bf = Behavior (a -> Bool) -> Event a -> Event a
    forall a. Behavior (a -> Bool) -> Event a -> Event a
    filterApply (Bool -> a -> Bool
    forall a b. a -> b -> a
    const (Bool -> a -> Bool) -> Behavior Bool -> Behavior (a -> Bool)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Behavior Bool
    bf)

    -- | Split event occurrences according to a tag.
    -- The 'Left' values go into the left component while the 'Right' values
    -- go into the right component of the result.
    split :: Event (Either a b) -> (Event a, Event b)
    split :: forall a b. Event (Either a b) -> (Event a, Event b)
    split Event (Either a b)
    e = (Event (Maybe a) -> Event a
    forall a. Event (Maybe a) -> Event a
    filterJust (Event (Maybe a) -> Event a) -> Event (Maybe a) -> Event a
    forall a b. (a -> b) -> a -> b
    $ Either a b -> Maybe a
    forall a b. Either a b -> Maybe a
    fromLeft (Either a b -> Maybe a) -> Event (Either a b) -> Event (Maybe a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Event (Either a b)
    e, Event (Maybe b) -> Event b
    forall a. Event (Maybe a) -> Event a
    filterJust (Event (Maybe b) -> Event b) -> Event (Maybe b) -> Event b
    forall a b. (a -> b) -> a -> b
    $ Either a b -> Maybe b
    forall a b. Either a b -> Maybe b
    fromRight (Either a b -> Maybe b) -> Event (Either a b) -> Event (Maybe b)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Event (Either a b)
    e)
        where
        fromLeft :: Either a b -> Maybe a
        fromLeft :: forall a b. Either a b -> Maybe a
    fromLeft  (Left  a
    a) = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    a
        fromLeft  (Right b
    _) = Maybe a
    forall a. Maybe a
    Nothing

        fromRight :: Either a b -> Maybe b
        fromRight :: forall a b. Either a b -> Maybe b
    fromRight (Left  a
    _) = Maybe b
    forall a. Maybe a
    Nothing
        fromRight (Right b
    b) = b -> Maybe b
    forall a. a -> Maybe a
    Just b
    b

    -- | Keep only the next occurence of an event.
    --
    -- @once@ also aids the garbage collector by indicating that the result event can be discarded after its only occurrence.
    --
    -- > once e = \time0 -> take 1 [(t, a) | (t, a) <- e, time0 <= t]
    once :: MonadMoment m => Event a -> m (Event a)
    once :: forall (m :: * -> *) a. MonadMoment m => Event a -> m (Event a)
    once Event a
    e = mdo
        e1 <- switchE e (never <$ e1)
        return e1

    -- $Accumulation.
    -- Note: All accumulation functions are strict in the accumulated value!
    --
    -- Note: The order of arguments is @acc -> (x,acc)@
    -- which is also the convention used by 'unfoldr' and 'State'.

    -- | Merge event streams whose values are functions.
    -- In case of simultaneous occurrences, the functions at the beginning
    -- of the list are applied /after/ the functions at the end.
    --
    -- > unions [] = never
    -- > unions xs = foldr1 (unionWith (.)) xs
    --
    -- Very useful in conjunction with accumulation functions like 'accumB'
    -- and 'accumE'.
    unions :: [Event (a -> a)] -> Event (a -> a)
    unions :: forall a. [Event (a -> a)] -> Event (a -> a)
    unions [] = Event (a -> a)
    forall a. Event a
    never
    unions [Event (a -> a)]
    xs = (Event (a -> a) -> Event (a -> a) -> Event (a -> a))
    -> [Event (a -> a)] -> Event (a -> a)
    forall a. (a -> a -> a) -> [a] -> a
    forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
    foldr1 (((a -> a) -> (a -> a) -> a -> a)
    -> Event (a -> a) -> Event (a -> a) -> Event (a -> a)
    forall a. (a -> a -> a) -> Event a -> Event a -> Event a
    unionWith (a -> a) -> (a -> a) -> a -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    (.)) [Event (a -> a)]
    xs

    -- | The 'accumB' function accumulates event occurrences into a 'Behavior'.
    --
    -- The value is accumulated using 'accumE' and converted
    -- into a time-varying value using 'stepper'.
    --
    -- Example:
    --
    -- > accumB "x" [(time1,(++"y")),(time2,(++"z"))]
    -- >    = stepper "x" [(time1,"xy"),(time2,"xyz")]
    --
    -- Note: As with 'stepper', the value of the behavior changes \"slightly after\"
    -- the events occur. This allows for recursive definitions.
    accumB :: MonadMoment m => a -> Event (a -> a) -> m (Behavior a)
    accumB :: forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event (a -> a) -> m (Behavior a)
    accumB a
    acc Event (a -> a)
    e = a -> Event a -> m (Behavior a)
    forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event a -> m (Behavior a)
    stepper a
    acc (Event a -> m (Behavior a)) -> m (Event a) -> m (Behavior a)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< a -> Event (a -> a) -> m (Event a)
    forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event (a -> a) -> m (Event a)
    accumE a
    acc Event (a -> a)
    e

    -- | Efficient combination of 'accumE' and 'accumB'.
    mapAccum :: MonadMoment m => acc -> Event (acc -> (x,acc)) -> m (Event x, Behavior acc)
    mapAccum :: forall (m :: * -> *) acc x.
    MonadMoment m =>
    acc -> Event (acc -> (x, acc)) -> m (Event x, Behavior acc)
    mapAccum acc
    acc Event (acc -> (x, acc))
    ef = do
            e <- (x, acc) -> Event ((x, acc) -> (x, acc)) -> m (Event (x, acc))
    forall (m :: * -> *) a.
    MonadMoment m =>
    a -> Event (a -> a) -> m (Event a)
    accumE  (x
    forall a. HasCallStack => a
    undefined,acc
    acc) ((acc -> (x, acc)) -> (x, acc) -> (x, acc)
    forall {t} {b} {a}. (t -> b) -> (a, t) -> b
    lift ((acc -> (x, acc)) -> (x, acc) -> (x, acc))
    -> Event (acc -> (x, acc)) -> Event ((x, acc) -> (x, acc))
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Event (acc -> (x, acc))
    ef)
            b <- stepper acc (snd <$> e)
            return (fst <$> e, b)
        where
        lift :: (t -> b) -> (a, t) -> b
    lift t -> b
    f (a
    _,t
    acc) = t
    acc t -> b -> b
    forall a b. a -> b -> b
    `seq` t -> b
    f t
    acc