-- | FRP main types and combinators
module Dyna.Brick.Frp(
  -- * Events
  Evt,
  once,
  never,
  -- * Dynamics
  Dyn,
  constDyn,
  -- ** Observing the Dyn
  DynRef,
  runDyn,
  readDyn,
  cancelDyn,

  -- * Control
  newEvt,
  newDyn,

  -- * API
  -- * Event API
  scan,
  scanMay,
  mapMay,
  foldMaps,
  accum,
  accumB,
  accumMay,
  filters,
  filterJust,
  whens,
  splits,
  lefts,
  rights,
  iterates,
  withIterates,

  fix1,
  fix2,
  fix3,
  fix4,
  switch,
  joins,

  delay,
  delayFork,

  sums,
  sumD,
  integrate,
  integrate2,
  products,
  count,
  withCount,
  appends,
  takes,
  drops,
  takesWhile,
  dropsWhile,
  cycles,
  listAt,
  toToggle,

  races,
  forks,
  forevers,
  folds,
  foldls,
  foldls',
  foldrs,
  foldrs',
  prints,
  putStrLns,
  -- * Event/Dynamic interaction
  hold,
  unhold,
  scanD,
  scanMayD,
  switchD,
  switchDyn,
  apply,
  applyMay,
  snap,
  attach,
  attachWith,
  attachWithMay,
  (<@>),
  (<@),
  -- * Effectful API
  RunFunctor(..),
  foreach,
  posteach,
  iterates',
  scan',
  scanMay',
  accum',
  accumMay',
  filters',
  mapMay',
  apply',
  applyMay',
  -- * Utilities

  -- **  Channels (interaction with the world)
  mchanEvt,
  tchanEvt,
  uchanEvt,

  -- ** Clock
  clock,
  pulse,
  ticks,
  timer,
  timerD,
  -- ** Random
  toRandom,
  toRandomR,
  withRandom,
  withRandomR,
  oneOf,
  withOneOf,
  freqOf,
  withFreqOf,
  randSkip,
  randSkipBy,

  -- * Re-exports
  liftA2,
  liftA3,
) where

import Control.Applicative (liftA2, liftA3)
import Control.Concurrent.Chan qualified as M
import Control.Concurrent.STM
import Control.Concurrent.Chan.Unagi (InChan)
import Data.Bifunctor
import Data.Time
import System.Random
import Data.VectorSpace

import Dyna.Brick.Types
import Dyna qualified as D

infixl 4 <@>
infixl 4 <@

-- | Reference to running dynamic process by which we can query values (@readDyn@).
-- Also note that we no longer need the reference we should release the resources
-- by calling @cancelDyn@.
newtype DynRef a = DynRef { DynRef a -> DynRef Run a
unDynRef :: D.DynRef Run a }

-- | Runs dynamic within the scope of the function.
-- It provides a callback with dyn getter as argument and after
-- callback finishes it shutdowns the dyn process.
withDyn :: Dyn a -> (Run a -> Run b) -> Run b
withDyn :: Dyn a -> (Run a -> Run b) -> Run b
withDyn (Dyn Dyn Run a
dyn) Run a -> Run b
f = Dyn Run a -> (Run a -> Run b) -> Run b
forall (m :: * -> *) a b. Frp m => Dyn m a -> (m a -> m b) -> m b
D.withDyn Dyn Run a
dyn Run a -> Run b
f

-- | Dyn that is constructed from effectful callback.
constDyn :: Run a -> Dyn a
constDyn :: Run a -> Dyn a
constDyn Run a
act = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run a -> Dyn a) -> Dyn Run a -> Dyn a
forall a b. (a -> b) -> a -> b
$ Run a -> Dyn Run a
forall (m :: * -> *) a. Frp m => m a -> Dyn m a
D.constDyn Run a
act

-- | Executes dynamic for observation. The dynamic is step-wise constant
-- function that is driven by some event stream. The function runs the event stream
-- process in background and samples the updated state.
--
-- We can observe the value with @readDyn@. We need to shut down the stream when
-- we no longer need it with @cancelDyn@ function.
runDyn :: Dyn a -> Run (DynRef a)
runDyn :: Dyn a -> Run (DynRef a)
runDyn (Dyn Dyn Run a
d) = DynRef Run a -> DynRef a
forall a. DynRef Run a -> DynRef a
DynRef (DynRef Run a -> DynRef a) -> Run (DynRef Run a) -> Run (DynRef a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Dyn Run a -> Run (DynRef Run a)
forall (m :: * -> *) a. Frp m => Dyn m a -> m (DynRef m a)
D.runDyn Dyn Run a
d
--
-- | Event that happens only once and happens right away.
once :: Run a -> Evt a
once :: Run a -> Evt a
once Run a
ask = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => m a -> Evt m a
D.once Run a
ask

-- | Event that never happens. Callback function is ignored.
never :: Evt a
never :: Evt a
never = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
forall (m :: * -> *) a. Frp m => Evt m a
D.never

-- | Runs the argument event stream as background process
-- and produces event stream that is fed with events over channel (unagi-channel package).
-- When result event stream shuts down the background process also shuts down.
newEvt :: Evt a -> Run (Evt a)
newEvt :: Evt a -> Run (Evt a)
newEvt (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Run (Evt Run a) -> Run (Evt a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Evt Run a -> Run (Evt Run a)
forall (m :: * -> *) a. Frp m => Evt m a -> m (Evt m a)
D.newEvt Evt Run a
evt

-- | Runs the dynamic process in background and returns dynamic
-- that just samples the background proces with @readDyn@.
newDyn :: Dyn a -> Run (Dyn a)
newDyn :: Dyn a -> Run (Dyn a)
newDyn (Dyn Dyn Run a
dyn) = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run a -> Dyn a) -> Run (Dyn Run a) -> Run (Dyn a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Dyn Run a -> Run (Dyn Run a)
forall (m :: * -> *) a. Frp m => Dyn m a -> m (Dyn m a)
D.newDyn Dyn Run a
dyn

-- | Accumulate over event stream.
accum :: (a -> s -> (b, s)) -> s -> Evt a -> Evt b
accum :: (a -> s -> (b, s)) -> s -> Evt a -> Evt b
accum a -> s -> (b, s)
f s
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> s -> (b, s)) -> s -> Evt Run a -> Evt Run b
forall (m :: * -> *) a s b.
Frp m =>
(a -> s -> (b, s)) -> s -> Evt m a -> Evt m b
D.accum a -> s -> (b, s)
f s
s Evt Run a
evt

-- | Accumulate over event stream.
accum' :: (a -> s -> Run (b, s)) -> s -> Evt a -> Evt b
accum' :: (a -> s -> Run (b, s)) -> s -> Evt a -> Evt b
accum' a -> s -> Run (b, s)
f s
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> s -> Run (b, s)) -> s -> Evt Run a -> Evt Run b
forall (m :: * -> *) a s b.
Frp m =>
(a -> s -> m (b, s)) -> s -> Evt m a -> Evt m b
D.accum' a -> s -> Run (b, s)
f s
s Evt Run a
evt

-- | Accumulate over event stream.
accumMay :: (a -> s -> Maybe (b, s)) -> s -> Evt a -> Evt b
accumMay :: (a -> s -> Maybe (b, s)) -> s -> Evt a -> Evt b
accumMay a -> s -> Maybe (b, s)
f s
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> s -> Maybe (b, s)) -> s -> Evt Run a -> Evt Run b
forall (m :: * -> *) a s b.
Frp m =>
(a -> s -> Maybe (b, s)) -> s -> Evt m a -> Evt m b
D.accumMay a -> s -> Maybe (b, s)
f s
s Evt Run a
evt

-- | Accumulate over event stream.
accumMay' :: (a -> s -> Run (Maybe (b, s))) -> s -> Evt a -> Evt b
accumMay' :: (a -> s -> Run (Maybe (b, s))) -> s -> Evt a -> Evt b
accumMay' a -> s -> Run (Maybe (b, s))
f s
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> s -> Run (Maybe (b, s))) -> s -> Evt Run a -> Evt Run b
forall (m :: * -> *) a s b.
Frp m =>
(a -> s -> m (Maybe (b, s))) -> s -> Evt m a -> Evt m b
D.accumMay' a -> s -> Run (Maybe (b, s))
f s
s Evt Run a
evt

-- | scan over event stream. Example:
--
-- > naturals = scan (+) 0 pulse
scan :: (a -> b -> b) -> b -> Evt a -> Evt b
scan :: (a -> b -> b) -> b -> Evt a -> Evt b
scan a -> b -> b
f b
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b) -> b -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> b) -> b -> Evt m a -> Evt m b
D.scan a -> b -> b
f b
s  Evt Run a
evt

-- | scan over event stream with effectful function.
scan' :: (a -> b -> Run b) -> b -> Evt a -> Evt b
scan' :: (a -> b -> Run b) -> b -> Evt a -> Evt b
scan' a -> b -> Run b
f b
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> b -> Run b) -> b -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> m b) -> b -> Evt m a -> Evt m b
D.scan' a -> b -> Run b
f b
s Evt Run a
evt

-- | scan combined with filter. If accumulator function produces @Nothing@ on event then
-- that event is ignored and state is kept to previous state.
scanMay :: (a -> b -> Maybe b) -> b -> Evt a -> Evt b
scanMay :: (a -> b -> Maybe b) -> b -> Evt a -> Evt b
scanMay a -> b -> Maybe b
f b
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> b -> Maybe b) -> b -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> Maybe b) -> b -> Evt m a -> Evt m b
D.scanMay a -> b -> Maybe b
f b
s Evt Run a
evt

-- | scan combined with filter for effectful function. See @scanMay@ for details.
scanMay' :: (a -> b -> Run (Maybe b)) -> b -> Evt a -> Evt b
scanMay' :: (a -> b -> Run (Maybe b)) -> b -> Evt a -> Evt b
scanMay' a -> b -> Run (Maybe b)
f b
s (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> b -> Run (Maybe b)) -> b -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> m (Maybe b)) -> b -> Evt m a -> Evt m b
D.scanMay' a -> b -> Run (Maybe b)
f b
s Evt Run a
evt

-- | Combo of @fmap@ and @appendE@
foldMaps :: Monoid b => (a -> b) -> Evt a -> Evt b
foldMaps :: (a -> b) -> Evt a -> Evt b
foldMaps a -> b
f Evt a
evt = Evt b -> Evt b
forall a. Monoid a => Evt a -> Evt a
appends ((a -> b) -> Evt a -> Evt b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> b
f Evt a
evt)

-- | Repeatedly executes the same event stream
races :: Evt a -> Evt a -> Evt a
races :: Evt a -> Evt a -> Evt a
races (Evt Evt Run a
evtA) (Evt Evt Run a
evtB) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m a -> Evt m a
D.races Evt Run a
evtA Evt Run a
evtB)

-- | Repeatedly executes the same event stream
forks :: Evt a -> Evt a
forks :: Evt a -> Evt a
forks (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m a
D.forks Evt Run a
evt)

-- | Repeatedly executes the same event stream
forevers :: Evt a -> Evt a
forevers :: Evt a -> Evt a
forevers (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m a
D.forevers Evt Run a
evt)

-- | Iterates over event stream. It's like scan but it ignores the values of underying stream
-- and starts with initial value as first element.
iterates :: (a -> a) -> a -> Evt b -> Evt a
iterates :: (a -> a) -> a -> Evt b -> Evt a
iterates a -> a
f a
val (Evt Evt Run b
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> a) -> a -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b.
Frp m =>
(a -> a) -> a -> Evt m b -> Evt m a
D.iterates a -> a
f a
val Evt Run b
evt

withIterates :: (a -> a) -> a -> Evt b -> Evt (a, b)
withIterates :: (a -> a) -> a -> Evt b -> Evt (a, b)
withIterates a -> a
f a
val (Evt Evt Run b
evt) = Evt Run (a, b) -> Evt (a, b)
forall a. Evt Run a -> Evt a
Evt (Evt Run (a, b) -> Evt (a, b)) -> Evt Run (a, b) -> Evt (a, b)
forall a b. (a -> b) -> a -> b
$ (a -> a) -> a -> Evt Run b -> Evt Run (a, b)
forall (m :: * -> *) a b.
Frp m =>
(a -> a) -> a -> Evt m b -> Evt m (a, b)
D.withIterates a -> a
f a
val Evt Run b
evt

-- | Effectful version for @iterateE@.
iterates' :: (a -> Run a) -> a -> Evt b -> Evt a
iterates' :: (a -> Run a) -> a -> Evt b -> Evt a
iterates' a -> Run a
f a
val (Evt Evt Run b
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Run a) -> a -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b.
Frp m =>
(a -> m a) -> a -> Evt m b -> Evt m a
D.iterates' a -> Run a
f a
val Evt Run b
evt

-- | Reads current dynamic value.
readDyn :: DynRef  a -> Run a
readDyn :: DynRef a -> Run a
readDyn (DynRef DynRef Run a
ref) = DynRef Run a -> Run a
forall (m :: * -> *) a. Frp m => DynRef m a -> m a
D.readDyn DynRef Run a
ref

-- | Shuts down the background process for dynamic and releases resulrces for
-- event stream that drives the dynamic.
cancelDyn :: DynRef a -> Run ()
cancelDyn :: DynRef a -> Run ()
cancelDyn (DynRef DynRef Run a
ref) = DynRef Run a -> Run ()
forall (m :: * -> *) a. Frp m => DynRef m a -> m ()
D.cancelDyn DynRef Run a
ref

-- | Turns event stream to dynamic. It holds the values of
-- events until the next event happen. It starts with initial value.
--
-- > hold initVal events = ...
hold :: a -> Evt a -> Dyn a
hold :: a -> Evt a -> Dyn a
hold a
s (Evt Evt Run a
evt) = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run a -> Dyn a) -> Dyn Run a -> Dyn a
forall a b. (a -> b) -> a -> b
$ a -> Evt Run a -> Dyn Run a
forall (m :: * -> *) a. Frp m => a -> Evt m a -> Dyn m a
D.hold a
s Evt Run a
evt

-- | Counts how many events accured so far on the stream.
count :: Evt a -> Evt Int
count :: Evt a -> Evt Int
count (Evt Evt Run a
evt) = Evt Run Int -> Evt Int
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run Int
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m Int
D.count Evt Run a
evt)

withCount :: Evt a -> Evt (Int, a)
withCount :: Evt a -> Evt (Int, a)
withCount (Evt Evt Run a
evt) = Evt Run (Int, a) -> Evt (Int, a)
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run (Int, a)
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m (Int, a)
D.withCount Evt Run a
evt)

-- | Turns dynamic into event stream of underlying events
-- that trigger dynamic updates.
unhold :: Dyn a -> Evt a
unhold :: Dyn a -> Evt a
unhold (Dyn Dyn Run a
dyn) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Dyn m a -> Evt m a
D.unhold Dyn Run a
dyn

-- | scans over event stream and converts it to dynamic.
scanD :: (a -> b -> b) -> b -> Evt a -> Dyn b
scanD :: (a -> b -> b) -> b -> Evt a -> Dyn b
scanD a -> b -> b
f b
s (Evt Evt Run a
evt) = Dyn Run b -> Dyn b
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run b -> Dyn b) -> Dyn Run b -> Dyn b
forall a b. (a -> b) -> a -> b
$ (a -> b -> b) -> b -> Evt Run a -> Dyn Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> b) -> b -> Evt m a -> Dyn m b
D.scanD a -> b -> b
f b
s Evt Run a
evt

-- | Accumulates the values with event stream that produce functions.
accumB :: a -> Evt (a -> a) -> Dyn a
accumB :: a -> Evt (a -> a) -> Dyn a
accumB a
a (Evt Evt Run (a -> a)
evt) = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run a -> Dyn a) -> Dyn Run a -> Dyn a
forall a b. (a -> b) -> a -> b
$ a -> Evt Run (a -> a) -> Dyn Run a
forall (m :: * -> *) a. Frp m => a -> Evt m (a -> a) -> Dyn m a
D.accumB a
a Evt Run (a -> a)
evt

-- | Dynamic scan that can also filter out events. If Nothing is produced then the event is skipped.
scanMayD :: (a -> b -> Maybe b) -> b -> Evt a -> Dyn b
scanMayD :: (a -> b -> Maybe b) -> b -> Evt a -> Dyn b
scanMayD a -> b -> Maybe b
f b
s (Evt Evt Run a
evt) = Dyn Run b -> Dyn b
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run b -> Dyn b) -> Dyn Run b -> Dyn b
forall a b. (a -> b) -> a -> b
$ (a -> b -> Maybe b) -> b -> Evt Run a -> Dyn Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> Maybe b) -> b -> Evt m a -> Dyn m b
D.scanMayD a -> b -> Maybe b
f b
s Evt Run a
evt

-- | Adds some procedure to callback. Procedure is called prior to callback execution.
foreach :: (a -> Run ()) -> Evt a -> Evt a
foreach :: (a -> Run ()) -> Evt a -> Evt a
foreach a -> Run ()
call (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Run ()) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => (a -> m ()) -> Evt m a -> Evt m a
D.foreach a -> Run ()
call Evt Run a
evt

-- | Adds some procedure to callback. Procedure is called after callback execution.
posteach :: (a -> Run ()) -> Evt a -> Evt a
posteach :: (a -> Run ()) -> Evt a -> Evt a
posteach a -> Run ()
call (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Run ()) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => (a -> m ()) -> Evt m a -> Evt m a
D.posteach a -> Run ()
call Evt Run a
evt

--------------------------------------------------------------------------------
-- applications

-- | Applies a function to event stream value. The function is sampled
-- from dynamic process.
apply :: Dyn (a -> b) -> Evt a -> Evt b
apply :: Dyn (a -> b) -> Evt a -> Evt b
apply (Dyn Dyn Run (a -> b)
dyn) (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Dyn Run (a -> b) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
Dyn m (a -> b) -> Evt m a -> Evt m b
D.apply Dyn Run (a -> b)
dyn Evt Run a
evt

-- | Effectful variant of @apply@.
apply' :: Dyn (a -> Run b) -> Evt a -> Evt b
apply' :: Dyn (a -> Run b) -> Evt a -> Evt b
apply' (Dyn Dyn Run (a -> Run b)
dyn) (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Dyn Run (a -> Run b) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
Dyn m (a -> m b) -> Evt m a -> Evt m b
D.apply' Dyn Run (a -> Run b)
dyn Evt Run a
evt

-- | Infix variant of @apply@
(<@>) :: Dyn (a -> b) -> Evt a -> Evt b
<@> :: Dyn (a -> b) -> Evt a -> Evt b
(<@>) = Dyn (a -> b) -> Evt a -> Evt b
forall a b. Dyn (a -> b) -> Evt a -> Evt b
apply

-- | Infix variant of @snap@.
(<@) :: Dyn a -> Evt b -> Evt a
<@ :: Dyn a -> Evt b -> Evt a
(<@) = Dyn a -> Evt b -> Evt a
forall a b. Dyn a -> Evt b -> Evt a
snap

-- | Apply combined with filter.
applyMay :: Dyn (a -> Maybe b) -> Evt a -> Evt b
applyMay :: Dyn (a -> Maybe b) -> Evt a -> Evt b
applyMay (Dyn Dyn Run (a -> Maybe b)
dyn) (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Dyn Run (a -> Maybe b) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
Dyn m (a -> Maybe b) -> Evt m a -> Evt m b
D.applyMay Dyn Run (a -> Maybe b)
dyn Evt Run a
evt

-- | Effectful @applyMay@.
applyMay' :: Dyn (a -> Run (Maybe b)) -> Evt a -> Evt b
applyMay' :: Dyn (a -> Run (Maybe b)) -> Evt a -> Evt b
applyMay' (Dyn Dyn Run (a -> Run (Maybe b))
dyn) (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Dyn Run (a -> Run (Maybe b)) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
Dyn m (a -> m (Maybe b)) -> Evt m a -> Evt m b
D.applyMay' Dyn Run (a -> Run (Maybe b))
dyn Evt Run a
evt

-- | Snapshot of dynamic process with event stream. All values
-- in the event stream are substituted with current value of dynamic.
snap :: Dyn a -> Evt b -> Evt a
snap :: Dyn a -> Evt b -> Evt a
snap (Dyn Dyn Run a
dyn) (Evt Evt Run b
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Dyn Run a -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b. Frp m => Dyn m a -> Evt m b -> Evt m a
D.snap Dyn Run a
dyn Evt Run b
evt)

-- | Kind of @zipWith@ function for dynamics and event streams.
attach :: Dyn a -> Evt b -> Evt (a, b)
attach :: Dyn a -> Evt b -> Evt (a, b)
attach (Dyn Dyn Run a
dyn) (Evt Evt Run b
evt) = Evt Run (a, b) -> Evt (a, b)
forall a. Evt Run a -> Evt a
Evt (Evt Run (a, b) -> Evt (a, b)) -> Evt Run (a, b) -> Evt (a, b)
forall a b. (a -> b) -> a -> b
$ Dyn Run a -> Evt Run b -> Evt Run (a, b)
forall (m :: * -> *) a b.
Frp m =>
Dyn m a -> Evt m b -> Evt m (a, b)
D.attach Dyn Run a
dyn Evt Run b
evt

-- | Kind of @zipWith@ function for dynamics and event streams.
attachWith :: (a -> b -> c) -> Dyn a -> Evt b -> Evt c
attachWith :: (a -> b -> c) -> Dyn a -> Evt b -> Evt c
attachWith a -> b -> c
f (Dyn Dyn Run a
dyn) (Evt Evt Run b
evt) = Evt Run c -> Evt c
forall a. Evt Run a -> Evt a
Evt (Evt Run c -> Evt c) -> Evt Run c -> Evt c
forall a b. (a -> b) -> a -> b
$ (a -> b -> c) -> Dyn Run a -> Evt Run b -> Evt Run c
forall (m :: * -> *) a b c.
Frp m =>
(a -> b -> c) -> Dyn m a -> Evt m b -> Evt m c
D.attachWith a -> b -> c
f Dyn Run a
dyn Evt Run b
evt

-- | Attach with filtering. When @Nothing@ is produced event is omitted from the stream.
attachWithMay :: (a -> b -> Maybe c) -> Dyn a -> Evt b -> Evt c
attachWithMay :: (a -> b -> Maybe c) -> Dyn a -> Evt b -> Evt c
attachWithMay a -> b -> Maybe c
f (Dyn Dyn Run a
dyn) (Evt Evt Run b
evt) = Evt Run c -> Evt c
forall a. Evt Run a -> Evt a
Evt (Evt Run c -> Evt c) -> Evt Run c -> Evt c
forall a b. (a -> b) -> a -> b
$ (a -> b -> Maybe c) -> Dyn Run a -> Evt Run b -> Evt Run c
forall (m :: * -> *) a b c.
Frp m =>
(a -> b -> Maybe c) -> Dyn m a -> Evt m b -> Evt m c
D.attachWithMay a -> b -> Maybe c
f Dyn Run a
dyn Evt Run b
evt

-- | Map with filtering. When @Nothing@ is produced event is omitted from the stream.
mapMay :: (a -> Maybe b) -> Evt a -> Evt b
mapMay :: (a -> Maybe b) -> Evt a -> Evt b
mapMay a -> Maybe b
f (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> Maybe b) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> Maybe b) -> Evt m a -> Evt m b
D.mapMay a -> Maybe b
f Evt Run a
evt

-- | Map with filtering. When @Nothing@ is produced event is omitted from the stream.
mapMay' :: (a -> Run (Maybe b)) -> Evt a -> Evt b
mapMay' :: (a -> Run (Maybe b)) -> Evt a -> Evt b
mapMay' a -> Run (Maybe b)
f (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> Run (Maybe b)) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> m (Maybe b)) -> Evt m a -> Evt m b
D.mapMay' a -> Run (Maybe b)
f Evt Run a
evt

--------------------------------------------------------------------------------
-- filters

-- | Filtering of the event strewams. Only events that produce True remain in the stream.
filters :: (a -> Bool) -> Evt a -> Evt a
filters :: (a -> Bool) -> Evt a -> Evt a
filters a -> Bool
f (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => (a -> Bool) -> Evt m a -> Evt m a
D.filters a -> Bool
f Evt Run a
evt

-- | Effectful filtering for event streams.
filters' :: (a -> Run Bool) -> Evt a -> Evt a
filters' :: (a -> Run Bool) -> Evt a -> Evt a
filters' a -> Run Bool
f (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Run Bool) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a.
Frp m =>
(a -> m Bool) -> Evt m a -> Evt m a
D.filters' a -> Run Bool
f Evt Run a
evt

-- | Filters based on Maybe. If @Nothing@ is produced forthe event it is omitted from the stream.
filterJust :: Evt (Maybe a) -> Evt a
filterJust :: Evt (Maybe a) -> Evt a
filterJust (Evt Evt Run (Maybe a)
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Evt Run (Maybe a) -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m (Maybe a) -> Evt m a
D.filterJust Evt Run (Maybe a)
evt

-- | Filters with dynamic. When dynamic is true events pass through and when it's false
-- events are omitted.
whens :: Dyn Bool -> Evt a -> Evt a
whens :: Dyn Bool -> Evt a -> Evt a
whens (Dyn Dyn Run Bool
dyn) (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run Bool -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Dyn m Bool -> Evt m a -> Evt m a
D.whens Dyn Run Bool
dyn Evt Run a
evt

-- | Splits the either event stream.
splits :: Evt (Either a b) -> (Evt a, Evt b)
splits :: Evt (Either a b) -> (Evt a, Evt b)
splits Evt (Either a b)
evt = (Evt (Either a b) -> Evt a
forall a b. Evt (Either a b) -> Evt a
lefts Evt (Either a b)
evt, Evt (Either a b) -> Evt b
forall a b. Evt (Either a b) -> Evt b
rights Evt (Either a b)
evt)

-- | Gets all left events from the stream
lefts :: Evt (Either a b) -> Evt a
lefts :: Evt (Either a b) -> Evt a
lefts (Evt Evt Run (Either a b)
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Evt Run (Either a b) -> Evt Run a
forall (m :: * -> *) a b. Frp m => Evt m (Either a b) -> Evt m a
D.lefts Evt Run (Either a b)
evt

-- | Gets all right events from the stream
rights :: Evt (Either a b) -> Evt b
rights :: Evt (Either a b) -> Evt b
rights (Evt Evt Run (Either a b)
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Evt Run (Either a b) -> Evt Run b
forall (m :: * -> *) a b. Frp m => Evt m (Either a b) -> Evt m b
D.rights Evt Run (Either a b)
evt

-- | Takes only so many events from the stream
takes :: Int -> Evt a -> Evt a
takes :: Int -> Evt a -> Evt a
takes Int
n (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Int -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Int -> Evt m a -> Evt m a
D.takes Int
n Evt Run a
evt

-- | Takes only so many events from the stream
drops :: Int -> Evt a -> Evt a
drops :: Int -> Evt a -> Evt a
drops Int
n (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Int -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Int -> Evt m a -> Evt m a
D.drops Int
n Evt Run a
evt

-- | Takes events only while predicate is true.
takesWhile :: (a -> Bool) -> Evt a -> Evt a
takesWhile :: (a -> Bool) -> Evt a -> Evt a
takesWhile a -> Bool
pred (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => (a -> Bool) -> Evt m a -> Evt m a
D.takesWhile a -> Bool
pred Evt Run a
evt

-- | Takes events only while predicate is true.
dropsWhile :: (a -> Bool) -> Evt a -> Evt a
dropsWhile :: (a -> Bool) -> Evt a -> Evt a
dropsWhile a -> Bool
pred (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => (a -> Bool) -> Evt m a -> Evt m a
D.dropsWhile a -> Bool
pred Evt Run a
evt

-- | Takes elements from the list by index. If index is out of bounds the event is omitted.
listAt :: [a] -> Evt Int -> Evt a
listAt :: [a] -> Evt Int -> Evt a
listAt [a]
vals (Evt Evt Run Int
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ [a] -> Evt Run Int -> Evt Run a
forall (m :: * -> *) a. Frp m => [a] -> Evt m Int -> Evt m a
D.listAt [a]
vals Evt Run Int
evt

-- | Turns event stream to toggle stream. It produce cyclic sequence of [True, False]
toToggle :: Evt a -> Evt Bool
toToggle :: Evt a -> Evt Bool
toToggle (Evt Evt Run a
evt) = Evt Run Bool -> Evt Bool
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run Bool
forall (m :: * -> *) a. Frp m => Evt m a -> Evt m Bool
D.toToggle Evt Run a
evt)

-- | Cycles the values in the list over event sream.
cycles :: [a] -> Evt b -> Evt a
cycles :: [a] -> Evt b -> Evt a
cycles [a]
vals (Evt Evt Run b
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt ([a] -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b. Frp m => [a] -> Evt m b -> Evt m a
D.cycles [a]
vals Evt Run b
evt)

-- | Sums all the elements in the event stream
sums :: (Num a) => Evt a -> Evt a
sums :: Evt a -> Evt a
sums = (a -> a -> a) -> a -> Evt a -> Evt a
forall a b. (a -> b -> b) -> b -> Evt a -> Evt b
scan a -> a -> a
forall a. Num a => a -> a -> a
(+) a
0

-- | Sums all the elements in the event stream
sumD :: (Num a) => Float -> Dyn a -> Dyn a
sumD :: Float -> Dyn a -> Dyn a
sumD Float
dt (Dyn Dyn Run a
dyn) = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (NominalDiffTime -> Dyn Run a -> Dyn Run a
forall (m :: * -> *) a.
(Frp m, Num a) =>
NominalDiffTime -> Dyn m a -> Dyn m a
D.sumD (Float -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
dt) Dyn Run a
dyn)

integrate :: (VectorSpace v, Scalar v ~ Float) => Float -> Dyn v -> Dyn v
integrate :: Float -> Dyn v -> Dyn v
integrate Float
dt (Dyn Dyn Run v
dyn) = Dyn Run v -> Dyn v
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run v -> Dyn v) -> Dyn Run v -> Dyn v
forall a b. (a -> b) -> a -> b
$ Scalar v -> Dyn Run v -> Dyn Run v
forall (m :: * -> *) v.
(Frp m, VectorSpace v, Real (Scalar v), Fractional (Scalar v)) =>
Scalar v -> Dyn m v -> Dyn m v
D.integrate Float
Scalar v
dt Dyn Run v
dyn

integrate2 :: (VectorSpace v, Scalar v ~ Float) => Float -> Dyn v -> Dyn v
integrate2 :: Float -> Dyn v -> Dyn v
integrate2 Float
dt (Dyn Dyn Run v
dyn) = Dyn Run v -> Dyn v
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run v -> Dyn v) -> Dyn Run v -> Dyn v
forall a b. (a -> b) -> a -> b
$ Scalar v -> Dyn Run v -> Dyn Run v
forall (m :: * -> *) v.
(Frp m, VectorSpace v, Real (Scalar v), Fractional (Scalar v)) =>
Scalar v -> Dyn m v -> Dyn m v
D.integrate2 Float
Scalar v
dt Dyn Run v
dyn

-- | Finds the product of all elements in the event stream.
products :: (Num a) => Evt a -> Evt a
products :: Evt a -> Evt a
products = (a -> a -> a) -> a -> Evt a -> Evt a
forall a b. (a -> b -> b) -> b -> Evt a -> Evt b
scan a -> a -> a
forall a. Num a => a -> a -> a
(*) a
1

-- | Monoidal append of all elements in the stream
appends :: (Monoid a) => Evt a -> Evt a
appends :: Evt a -> Evt a
appends (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt Run a
forall (m :: * -> *) a. (Frp m, Monoid a) => Evt m a -> Evt m a
D.appends Evt Run a
evt)

-- | Monoidal fold for event streams, note that stream have to be finite for
-- the function to complete
folds :: Monoid a => Evt a -> Run a
folds :: Evt a -> Run a
folds = (a -> a -> a) -> a -> Evt a -> Run a
forall b a. (b -> a -> b) -> b -> Evt a -> Run b
foldls a -> a -> a
forall a. Semigroup a => a -> a -> a
(<>) a
forall a. Monoid a => a
mempty

-- | Left fold for event streams, note that stream have to be finite for
-- the function to complete
foldls :: (b -> a -> b) -> b -> Evt a -> Run b
foldls :: (b -> a -> b) -> b -> Evt a -> Run b
foldls b -> a -> b
f b
s (Evt Evt Run a
evt) = (b -> a -> b) -> b -> Evt Run a -> Run b
forall (m :: * -> *) b a.
Frp m =>
(b -> a -> b) -> b -> Evt m a -> m b
D.foldls b -> a -> b
f b
s Evt Run a
evt

-- | Effectful left fold
foldls' :: (b -> a -> Run b) -> b -> Evt a -> Run b
foldls' :: (b -> a -> Run b) -> b -> Evt a -> Run b
foldls' b -> a -> Run b
f b
s (Evt Evt Run a
evt) = (b -> a -> Run b) -> b -> Evt Run a -> Run b
forall (m :: * -> *) b a.
Frp m =>
(b -> a -> m b) -> b -> Evt m a -> m b
D.foldls' b -> a -> Run b
f b
s Evt Run a
evt

-- | Right fold for event streams, note that stream have to be finite for
-- the function to complete
foldrs :: (a -> b -> b) -> b -> Evt a -> Run b
foldrs :: (a -> b -> b) -> b -> Evt a -> Run b
foldrs a -> b -> b
f b
s (Evt Evt Run a
evt) = (a -> b -> b) -> b -> Evt Run a -> Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> b) -> b -> Evt m a -> m b
D.foldrs a -> b -> b
f b
s Evt Run a
evt

-- | Effectful right fold
foldrs' :: (a -> b -> Run b) -> b -> Evt a -> Run b
foldrs' :: (a -> b -> Run b) -> b -> Evt a -> Run b
foldrs' a -> b -> Run b
f b
s (Evt Evt Run a
evt) = (a -> b -> Run b) -> b -> Evt Run a -> Run b
forall (m :: * -> *) a b.
Frp m =>
(a -> b -> m b) -> b -> Evt m a -> m b
D.foldrs' a -> b -> Run b
f b
s Evt Run a
evt

-- | Starts event stream process and as callback prints it values.
prints :: (Show a) => Evt a -> Run ()
prints :: Evt a -> Run ()
prints (Evt Evt Run a
evt) = Evt Run a -> Run ()
forall (m :: * -> *) a. (Frp m, Show a) => Evt m a -> m ()
D.prints Evt Run a
evt

-- | Starts event stream process and as callback prints it values.
putStrLns :: Evt String -> Run ()
putStrLns :: Evt String -> Run ()
putStrLns (Evt Evt Run String
evt) = Evt Run String -> Run ()
forall (m :: * -> *). Frp m => Evt m String -> m ()
D.putStrLns Evt Run String
evt

-- | Queries the event stream form dynamic and runs it all next event streams are ignored.
switchDyn :: Dyn (Evt a) -> Evt a
switchDyn :: Dyn (Evt a) -> Evt a
switchDyn (Dyn Dyn Run (Evt a)
dyn) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run (Evt Run a) -> Evt Run a
forall (m :: * -> *) a. Frp m => Dyn m (Evt m a) -> Evt m a
D.switchDyn (Dyn Run (Evt Run a) -> Evt Run a)
-> Dyn Run (Evt Run a) -> Evt Run a
forall a b. (a -> b) -> a -> b
$ (Evt a -> Evt Run a) -> Dyn Run (Evt a) -> Dyn Run (Evt Run a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Dyn Run (Evt a)
dyn

-- | Joins event stream of streams. If stream is started it runs until the end.
joins :: Evt (Evt a) -> Evt a
joins :: Evt (Evt a) -> Evt a
joins (Evt Evt Run (Evt a)
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Evt Run (Evt Run a) -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m (Evt m a) -> Evt m a
D.joins (Evt Run (Evt Run a) -> Evt Run a)
-> Evt Run (Evt Run a) -> Evt Run a
forall a b. (a -> b) -> a -> b
$ (Evt a -> Evt Run a) -> Evt Run (Evt a) -> Evt Run (Evt Run a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt Run (Evt a)
evt

-- | Recursion on event streams. As event streams are functions we can not use
-- normal recursion that haskell provides. It will stuck the execution.
-- But we can use @fix1@ to create event stream that feeds back the events to itself.
--
-- Note that any sort of recursion can be implemented with @fix1@.
-- For example if we need 3-recursive event stream:
--
--  > fix3 ::
--  >      (Evt a -> Evt b -> Evt c -> (Evt a, Evt b, Evt c))
--  >   -> (Evt a, Evt b, Evt c)
--
-- we can use sum tpye tags
-- to join it to single stream:
--
-- > data Tag a b c = TagA a | TagB b | TagC c
--
-- > fix3 f = unwrap $ fix1 g
-- >   where
-- >      g x = wrap (f (unwrapA x) (unwrapB x) (unwrapC x))
-- >
-- >      wrap a b c = mconcat [TagA <$> a, TagB <$> b, TagC <$> c]
-- >      unwrap evt = (unwrapA evt, unwrapB evt, unwrapC evt)
-- >
-- >      unwrapA = flip mapMay $ \x -> case x of
-- >                                  TagA a -> Just a
-- >                                  _      -> Nothing
--
-- We can use this trck with any number of streams. There are helper functions: @fix2@, @fix3@, @fix4@
fix1 :: (Evt a -> Run (Evt a)) -> Evt a
fix1 :: (Evt a -> Run (Evt a)) -> Evt a
fix1 Evt a -> Run (Evt a)
f = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ (Evt Run a -> Run (Evt Run a)) -> Evt Run a
forall (m :: * -> *) a.
Frp m =>
(Evt m a -> m (Evt m a)) -> Evt m a
D.fix1 ((Evt a -> Evt Run a) -> Run (Evt a) -> Run (Evt Run a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt (Run (Evt a) -> Run (Evt Run a))
-> (Evt Run a -> Run (Evt a)) -> Evt Run a -> Run (Evt Run a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Evt a -> Run (Evt a)
f (Evt a -> Run (Evt a))
-> (Evt Run a -> Evt a) -> Evt Run a -> Run (Evt a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt)

-- | Recursion for binary functions
fix2 :: (Evt a -> Evt b -> Run (Evt a, Evt b)) -> (Evt a, Evt b)
fix2 :: (Evt a -> Evt b -> Run (Evt a, Evt b)) -> (Evt a, Evt b)
fix2 Evt a -> Evt b -> Run (Evt a, Evt b)
f = (Evt Run a -> Evt a)
-> (Evt Run b -> Evt b) -> (Evt Run a, Evt Run b) -> (Evt a, Evt b)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt ((Evt Run a, Evt Run b) -> (Evt a, Evt b))
-> (Evt Run a, Evt Run b) -> (Evt a, Evt b)
forall a b. (a -> b) -> a -> b
$ (Evt Run a -> Evt Run b -> Run (Evt Run a, Evt Run b))
-> (Evt Run a, Evt Run b)
forall (m :: * -> *) a b.
Frp m =>
(Evt m a -> Evt m b -> m (Evt m a, Evt m b)) -> (Evt m a, Evt m b)
D.fix2 (\Evt Run a
a Evt Run b
b -> (Evt a -> Evt Run a)
-> (Evt b -> Evt Run b) -> (Evt a, Evt b) -> (Evt Run a, Evt Run b)
forall (p :: * -> * -> *) a b c d.
Bifunctor p =>
(a -> b) -> (c -> d) -> p a c -> p b d
bimap Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt b -> Evt Run b
forall a. Evt a -> Evt Run a
unEvt ((Evt a, Evt b) -> (Evt Run a, Evt Run b))
-> Run (Evt a, Evt b) -> Run (Evt Run a, Evt Run b)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Evt a -> Evt b -> Run (Evt a, Evt b)
f (Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
a) (Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt Evt Run b
b))

-- | Recursion for ternary functions
fix3 ::
     (Evt a -> Evt b -> Evt c -> Run (Evt a, Evt b, Evt c))
  -> (Evt a, Evt b, Evt c)
fix3 :: (Evt a -> Evt b -> Evt c -> Run (Evt a, Evt b, Evt c))
-> (Evt a, Evt b, Evt c)
fix3 Evt a -> Evt b -> Evt c -> Run (Evt a, Evt b, Evt c)
f = (Evt Run a, Evt Run b, Evt Run c) -> (Evt a, Evt b, Evt c)
forall a a a.
(Evt Run a, Evt Run a, Evt Run a) -> (Evt a, Evt a, Evt a)
wrap ((Evt Run a, Evt Run b, Evt Run c) -> (Evt a, Evt b, Evt c))
-> (Evt Run a, Evt Run b, Evt Run c) -> (Evt a, Evt b, Evt c)
forall a b. (a -> b) -> a -> b
$ (Evt Run a
 -> Evt Run b -> Evt Run c -> Run (Evt Run a, Evt Run b, Evt Run c))
-> (Evt Run a, Evt Run b, Evt Run c)
forall (m :: * -> *) a b c.
Frp m =>
(Evt m a -> Evt m b -> Evt m c -> m (Evt m a, Evt m b, Evt m c))
-> (Evt m a, Evt m b, Evt m c)
D.fix3 (\Evt Run a
a Evt Run b
b Evt Run c
c -> (Evt a, Evt b, Evt c) -> (Evt Run a, Evt Run b, Evt Run c)
forall a a a.
(Evt a, Evt a, Evt a) -> (Evt Run a, Evt Run a, Evt Run a)
unwrap ((Evt a, Evt b, Evt c) -> (Evt Run a, Evt Run b, Evt Run c))
-> Run (Evt a, Evt b, Evt c)
-> Run (Evt Run a, Evt Run b, Evt Run c)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Evt a -> Evt b -> Evt c -> Run (Evt a, Evt b, Evt c)
f (Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
a) (Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt Evt Run b
b) (Evt Run c -> Evt c
forall a. Evt Run a -> Evt a
Evt Evt Run c
c))
  where
    wrap :: (Evt Run a, Evt Run a, Evt Run a) -> (Evt a, Evt a, Evt a)
wrap (Evt Run a
a, Evt Run a
b, Evt Run a
c) = (Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
a, Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
b, Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
c)
    unwrap :: (Evt a, Evt a, Evt a) -> (Evt Run a, Evt Run a, Evt Run a)
unwrap (Evt a
a, Evt a
b, Evt a
c) = (Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
a, Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
b, Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
c)

-- | Recursion for functions of four arguments
fix4 ::
     (Evt a -> Evt b -> Evt c -> Evt d -> Run (Evt a, Evt b, Evt c, Evt d))
  -> (Evt a, Evt b, Evt c, Evt d)
fix4 :: (Evt a
 -> Evt b -> Evt c -> Evt d -> Run (Evt a, Evt b, Evt c, Evt d))
-> (Evt a, Evt b, Evt c, Evt d)
fix4 Evt a
-> Evt b -> Evt c -> Evt d -> Run (Evt a, Evt b, Evt c, Evt d)
f = (Evt Run a, Evt Run b, Evt Run c, Evt Run d)
-> (Evt a, Evt b, Evt c, Evt d)
forall a a a a.
(Evt Run a, Evt Run a, Evt Run a, Evt Run a)
-> (Evt a, Evt a, Evt a, Evt a)
wrap ((Evt Run a, Evt Run b, Evt Run c, Evt Run d)
 -> (Evt a, Evt b, Evt c, Evt d))
-> (Evt Run a, Evt Run b, Evt Run c, Evt Run d)
-> (Evt a, Evt b, Evt c, Evt d)
forall a b. (a -> b) -> a -> b
$ (Evt Run a
 -> Evt Run b
 -> Evt Run c
 -> Evt Run d
 -> Run (Evt Run a, Evt Run b, Evt Run c, Evt Run d))
-> (Evt Run a, Evt Run b, Evt Run c, Evt Run d)
forall (m :: * -> *) a b c d.
Frp m =>
(Evt m a
 -> Evt m b
 -> Evt m c
 -> Evt m d
 -> m (Evt m a, Evt m b, Evt m c, Evt m d))
-> (Evt m a, Evt m b, Evt m c, Evt m d)
D.fix4 (\Evt Run a
a Evt Run b
b Evt Run c
c Evt Run d
d -> (Evt a, Evt b, Evt c, Evt d)
-> (Evt Run a, Evt Run b, Evt Run c, Evt Run d)
forall a a a a.
(Evt a, Evt a, Evt a, Evt a)
-> (Evt Run a, Evt Run a, Evt Run a, Evt Run a)
unwrap ((Evt a, Evt b, Evt c, Evt d)
 -> (Evt Run a, Evt Run b, Evt Run c, Evt Run d))
-> Run (Evt a, Evt b, Evt c, Evt d)
-> Run (Evt Run a, Evt Run b, Evt Run c, Evt Run d)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Evt a
-> Evt b -> Evt c -> Evt d -> Run (Evt a, Evt b, Evt c, Evt d)
f (Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
a) (Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt Evt Run b
b) (Evt Run c -> Evt c
forall a. Evt Run a -> Evt a
Evt Evt Run c
c) (Evt Run d -> Evt d
forall a. Evt Run a -> Evt a
Evt Evt Run d
d))
  where
    wrap :: (Evt Run a, Evt Run a, Evt Run a, Evt Run a)
-> (Evt a, Evt a, Evt a, Evt a)
wrap (Evt Run a
a, Evt Run a
b, Evt Run a
c, Evt Run a
d) = (Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
a, Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
b, Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
c, Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt Evt Run a
d)
    unwrap :: (Evt a, Evt a, Evt a, Evt a)
-> (Evt Run a, Evt Run a, Evt Run a, Evt Run a)
unwrap (Evt a
a, Evt a
b, Evt a
c, Evt a
d) = (Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
a, Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
b, Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
c, Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt a
d)

-- | Flattens event stream producer by switching between event streams.
-- When next event stream happens it shuts down the previous one.
switch :: Evt (Evt a) -> Evt a
switch :: Evt (Evt a) -> Evt a
switch (Evt Evt Run (Evt a)
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Evt Run (Evt Run a) -> Evt Run a
forall (m :: * -> *) a. Frp m => Evt m (Evt m a) -> Evt m a
D.switch (Evt Run (Evt Run a) -> Evt Run a)
-> Evt Run (Evt Run a) -> Evt Run a
forall a b. (a -> b) -> a -> b
$ (Evt a -> Evt Run a) -> Evt Run (Evt a) -> Evt Run (Evt Run a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Evt a -> Evt Run a
forall a. Evt a -> Evt Run a
unEvt Evt Run (Evt a)
evt

-- | Switches between dynamic producers.
switchD :: Dyn a -> Evt (Dyn a) -> Dyn a
switchD :: Dyn a -> Evt (Dyn a) -> Dyn a
switchD (Dyn Dyn Run a
d) (Evt Evt Run (Dyn a)
evts) = Dyn Run a -> Dyn a
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run a -> Dyn a) -> Dyn Run a -> Dyn a
forall a b. (a -> b) -> a -> b
$ Dyn Run a -> Evt Run (Dyn Run a) -> Dyn Run a
forall (m :: * -> *) a.
Frp m =>
Dyn m a -> Evt m (Dyn m a) -> Dyn m a
D.switchD Dyn Run a
d ((Dyn a -> Dyn Run a) -> Evt Run (Dyn a) -> Evt Run (Dyn Run a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Dyn a -> Dyn Run a
forall a. Dyn a -> Dyn Run a
unDyn Evt Run (Dyn a)
evts)

---------------------------------------------------------
-- channels

-- | Creates the event stream that listens to MVar based channel.
-- If any value is put chan the event stream fires the callback.
mchanEvt :: M.Chan a -> Evt a
mchanEvt :: Chan a -> Evt a
mchanEvt Chan a
mchan = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Chan a -> Evt Run a
forall (m :: * -> *) a. Frp m => Chan a -> Evt m a
D.mchanEvt Chan a
mchan

-- | Creates the event stream that listens to MVar based channel.
-- If any value is put chan the event stream fires the callback.
tchanEvt :: TChan a -> Evt a
tchanEvt :: TChan a -> Evt a
tchanEvt TChan a
tchan = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ TChan a -> Evt Run a
forall (m :: * -> *) a. Frp m => TChan a -> Evt m a
D.tchanEvt TChan a
tchan

-- | Creates the event stream that listens to unagi channel (package @unagi-chan@).
-- If any value is put chan the event stream fires the callback.
uchanEvt :: InChan a -> Evt a
uchanEvt :: InChan a -> Evt a
uchanEvt InChan a
uchan = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ InChan a -> Evt Run a
forall (m :: * -> *) a. Frp m => InChan a -> Evt m a
D.uchanEvt InChan a
uchan

---------------------------------------------------------------------------
-- utilities

-- | Queries current time periodically with given period in seconds.
clock :: NominalDiffTime -> Evt UTCTime
clock :: NominalDiffTime -> Evt UTCTime
clock NominalDiffTime
t = Evt Run UTCTime -> Evt UTCTime
forall a. Evt Run a -> Evt a
Evt (Evt Run UTCTime -> Evt UTCTime) -> Evt Run UTCTime -> Evt UTCTime
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Evt Run UTCTime
forall (m :: * -> *). Frp m => NominalDiffTime -> Evt m UTCTime
D.clock NominalDiffTime
t

-- | Produces pulse events with given period in seconds.
pulse :: NominalDiffTime -> Evt ()
pulse :: NominalDiffTime -> Evt ()
pulse NominalDiffTime
t = Evt Run () -> Evt ()
forall a. Evt Run a -> Evt a
Evt (Evt Run () -> Evt ()) -> Evt Run () -> Evt ()
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Evt Run ()
forall (m :: * -> *). Frp m => NominalDiffTime -> Evt m ()
D.pulse NominalDiffTime
t

-- | Produces pulse events with given period in seconds
-- and also tells how many seconds exactly has passed.
-- It can be useful for simulations of models that are based on differential equations.
-- As event streams carries how much time has passed between simulation steps.
ticks :: Float -> Evt Float
ticks :: Float -> Evt Float
ticks Float
t = Evt Run Float -> Evt Float
forall a. Evt Run a -> Evt a
Evt (Evt Run Float -> Evt Float) -> Evt Run Float -> Evt Float
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (NominalDiffTime -> Float)
-> Evt Run NominalDiffTime -> Evt Run Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NominalDiffTime -> Evt Run NominalDiffTime
forall (m :: * -> *).
Frp m =>
NominalDiffTime -> Evt m NominalDiffTime
D.ticks (Float -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
t)

-- | Timer behaves like tocks only it produces accumulated time since beginning
-- of the process. It calculates them by querying current time and suntracting start time from it.
--
-- It can be though of as:
--
-- > sumE ticks
timer :: Float -> Evt Float
timer :: Float -> Evt Float
timer Float
t = Evt Run Float -> Evt Float
forall a. Evt Run a -> Evt a
Evt (Evt Run Float -> Evt Float) -> Evt Run Float -> Evt Float
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (NominalDiffTime -> Float)
-> Evt Run NominalDiffTime -> Evt Run Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NominalDiffTime -> Evt Run NominalDiffTime
forall (m :: * -> *).
Frp m =>
NominalDiffTime -> Evt m NominalDiffTime
D.timer (Float -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
t)

-- | Continuous timeline updated at given interval.
timerD :: Float -> Dyn Float
timerD :: Float -> Dyn Float
timerD Float
t = Dyn Run Float -> Dyn Float
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run Float -> Dyn Float) -> Dyn Run Float -> Dyn Float
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Float
forall a b. (Real a, Fractional b) => a -> b
realToFrac (NominalDiffTime -> Float)
-> Dyn Run NominalDiffTime -> Dyn Run Float
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NominalDiffTime -> Dyn Run NominalDiffTime
forall (m :: * -> *).
Frp m =>
NominalDiffTime -> Dyn m NominalDiffTime
D.timerD (Float -> NominalDiffTime
forall a b. (Real a, Fractional b) => a -> b
realToFrac Float
t)

--------------------------------------------------------------------------------

-- | Substitutes values in event stream with random values.
toRandom :: (Random b) => Evt a -> Evt b
toRandom :: Evt a -> Evt b
toRandom (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ Evt Run a -> Evt Run b
forall (m :: * -> *) a b. (Frp m, Random b) => Evt m a -> Evt m b
D.toRandom Evt Run a
evt

-- | Substitutes values in event stream with random values from the given range.
toRandomR :: (Random b) => (b, b) -> Evt a -> Evt b
toRandomR :: (b, b) -> Evt a -> Evt b
toRandomR (b, b)
range (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (b, b) -> Evt Run a -> Evt Run b
forall (m :: * -> *) a b.
(Frp m, Random b) =>
(b, b) -> Evt m a -> Evt m b
D.toRandomR (b, b)
range Evt Run a
evt

-- | Substitutes values in event stream with random values.
withRandom :: (Random b) => Evt a -> Evt (b, a)
withRandom :: Evt a -> Evt (b, a)
withRandom (Evt Evt Run a
evt) = Evt Run (b, a) -> Evt (b, a)
forall a. Evt Run a -> Evt a
Evt (Evt Run (b, a) -> Evt (b, a)) -> Evt Run (b, a) -> Evt (b, a)
forall a b. (a -> b) -> a -> b
$ Evt Run a -> Evt Run (b, a)
forall (m :: * -> *) a b.
(Frp m, Random b) =>
Evt m a -> Evt m (b, a)
D.withRandom Evt Run a
evt

-- | Substitutes values in event stream with random values from the given range.
withRandomR :: Random b => (b, b) -> Evt a -> Evt (b, a)
withRandomR :: (b, b) -> Evt a -> Evt (b, a)
withRandomR (b, b)
range (Evt Evt Run a
evt) = Evt Run (b, a) -> Evt (b, a)
forall a. Evt Run a -> Evt a
Evt (Evt Run (b, a) -> Evt (b, a)) -> Evt Run (b, a) -> Evt (b, a)
forall a b. (a -> b) -> a -> b
$ (b, b) -> Evt Run a -> Evt Run (b, a)
forall (m :: * -> *) a b.
(Frp m, Random b) =>
(b, b) -> Evt m a -> Evt m (b, a)
D.withRandomR (b, b)
range Evt Run a
evt

-- | Picks at random one element from the list
oneOf :: [a] -> Evt b -> Evt a
oneOf :: [a] -> Evt b -> Evt a
oneOf [a]
xs (Evt Evt Run b
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ [a] -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b. Frp m => [a] -> Evt m b -> Evt m a
D.oneOf [a]
xs Evt Run b
evt

-- | Picks at random one element from the list
withOneOf :: [a] -> Evt b -> Evt (a, b)
withOneOf :: [a] -> Evt b -> Evt (a, b)
withOneOf [a]
xs (Evt Evt Run b
evt) = Evt Run (a, b) -> Evt (a, b)
forall a. Evt Run a -> Evt a
Evt ([a] -> Evt Run b -> Evt Run (a, b)
forall (m :: * -> *) a b. Frp m => [a] -> Evt m b -> Evt m (a, b)
D.withOneOf [a]
xs Evt Run b
evt)

-- | Picks at random one element from the list. We also provide distribution of events.
-- Probability to pick up the element. Sum of probabilities should equal to 1.
freqOf :: Dyn [(a, Rational)] -> Evt b -> Evt a
freqOf :: Dyn [(a, Rational)] -> Evt b -> Evt a
freqOf (Dyn Dyn Run [(a, Rational)]
dynVals) (Evt Evt Run b
evts) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run [(a, Rational)] -> Evt Run b -> Evt Run a
forall (m :: * -> *) a b.
(MonadRandom m, Frp m) =>
Dyn m [(a, Rational)] -> Evt m b -> Evt m a
D.freqOf Dyn Run [(a, Rational)]
dynVals Evt Run b
evts

-- | Picks at random one element from the list. We also provide distribution of events.
-- Probability to pick up the element. Sum of probabilities should equal to 1.
withFreqOf :: Dyn [(a, Rational)] -> Evt b -> Evt (a, b)
withFreqOf :: Dyn [(a, Rational)] -> Evt b -> Evt (a, b)
withFreqOf (Dyn Dyn Run [(a, Rational)]
dynVals) (Evt Evt Run b
evts) = Evt Run (a, b) -> Evt (a, b)
forall a. Evt Run a -> Evt a
Evt (Evt Run (a, b) -> Evt (a, b)) -> Evt Run (a, b) -> Evt (a, b)
forall a b. (a -> b) -> a -> b
$ Dyn Run [(a, Rational)] -> Evt Run b -> Evt Run (a, b)
forall (m :: * -> *) a b.
(MonadRandom m, Frp m) =>
Dyn m [(a, Rational)] -> Evt m b -> Evt m (a, b)
D.withFreqOf Dyn Run [(a, Rational)]
dynVals Evt Run b
evts

-- | Skips at random elements from the list. We provide frequency to skip events with dynamic first argument.
randSkip :: Dyn Double -> Evt a -> Evt a
randSkip :: Dyn Double -> Evt a -> Evt a
randSkip (Dyn Dyn Run Double
prob) (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run Double -> Evt Run a -> Evt Run a
forall (m :: * -> *) a. Frp m => Dyn m Double -> Evt m a -> Evt m a
D.randSkip Dyn Run Double
prob Evt Run a
evt

-- | Skips elements at random. The probability to skip element depends on the element itself.
randSkipBy :: Dyn (a -> Double) -> Evt a -> Evt a
randSkipBy :: Dyn (a -> Double) -> Evt a -> Evt a
randSkipBy  (Dyn Dyn Run (a -> Double)
prob) (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ Dyn Run (a -> Double) -> Evt Run a -> Evt Run a
forall (m :: * -> *) a.
Frp m =>
Dyn m (a -> Double) -> Evt m a -> Evt m a
D.randSkipBy Dyn Run (a -> Double)
prob Evt Run a
evt

--------------------------------------------------------------------------------

-- | Delays in the thread of execution. Note that it can interfere
-- and screw up functions like clock, timer, pulse, ticks
delay :: NominalDiffTime -> Evt a -> Evt a
delay :: NominalDiffTime -> Evt a -> Evt a
delay NominalDiffTime
dt (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Evt Run a -> Evt Run a
forall (m :: * -> *) a.
Frp m =>
NominalDiffTime -> Evt m a -> Evt m a
D.delay NominalDiffTime
dt Evt Run a
evt

-- | Delays in background by forking on each event.
-- Note tht if delayed event was put into background prior
-- to stopping of the main event stream it will fire anyway.
-- There is no way to stop it.
delayFork :: NominalDiffTime -> Evt a -> Evt a
delayFork :: NominalDiffTime -> Evt a -> Evt a
delayFork NominalDiffTime
dt (Evt Evt Run a
evt) = Evt Run a -> Evt a
forall a. Evt Run a -> Evt a
Evt (Evt Run a -> Evt a) -> Evt Run a -> Evt a
forall a b. (a -> b) -> a -> b
$ NominalDiffTime -> Evt Run a -> Evt Run a
forall (m :: * -> *) a.
Frp m =>
NominalDiffTime -> Evt m a -> Evt m a
D.delayFork NominalDiffTime
dt Evt Run a
evt

--------------------------------------------------------------------------------
-- effectful functor

class RunFunctor f where
  fmap' :: (a -> Run b) -> f a -> f b

instance RunFunctor Evt where
  fmap' :: (a -> Run b) -> Evt a -> Evt b
fmap' a -> Run b
f (Evt Evt Run a
evt) = Evt Run b -> Evt b
forall a. Evt Run a -> Evt a
Evt (Evt Run b -> Evt b) -> Evt Run b -> Evt b
forall a b. (a -> b) -> a -> b
$ (a -> Run b) -> Evt Run a -> Evt Run b
forall (f :: (* -> *) -> * -> *) (m :: * -> *) a b.
(FunctorM f, Frp m) =>
(a -> m b) -> f m a -> f m b
D.fmap' a -> Run b
f Evt Run a
evt

instance RunFunctor Dyn where
  fmap' :: (a -> Run b) -> Dyn a -> Dyn b
fmap' a -> Run b
f (Dyn Dyn Run a
dyn) = Dyn Run b -> Dyn b
forall a. Dyn Run a -> Dyn a
Dyn (Dyn Run b -> Dyn b) -> Dyn Run b -> Dyn b
forall a b. (a -> b) -> a -> b
$ (a -> Run b) -> Dyn Run a -> Dyn Run b
forall (f :: (* -> *) -> * -> *) (m :: * -> *) a b.
(FunctorM f, Frp m) =>
(a -> m b) -> f m a -> f m b
D.fmap' a -> Run b
f Dyn Run a
dyn