{-# LANGUAGE DoRec #-}
module Event where
import Control.Applicative
import Control.Monad
import Control.Monad.Fix
import Data.Maybe
import FRP.Elerea.Param
import Util
-- | Events are signals with an option type.
type Event a = Signal (Maybe a)
-- | Sample a signal whenever a changing condition is true.
ifE :: Signal Bool -> Signal a -> Event a
ifE c s = c >>= \b -> if b then Just <$> s else return Nothing
-- | Left-biased merge.
leftE :: Event a -> Event a -> Event a
leftE e1 e2 = e1 >>= maybeE e2
-- | Right-biased merge.
rightE :: Event a -> Event a -> Event a
rightE e1 e2 = e2 >>= maybeE e1
-- | Left-biased merge of several events.
mergeE :: [Event a] -> Event a
mergeE [] = return Nothing
mergeE (e:es) = e >>= maybeE (mergeE es)
-- | Maintain a changing list of entities fed in as events along with
-- a function to derive the corresponding signal of the removal
-- condition (the signal is removed when the associated removal signal
-- is 'True' for the first time).
collectE :: Event a -> (a -> Signal Bool) -> SignalGen p (Signal [a])
collectE e f = do
rec col <- delay [] col'
col' <- memo $ filterM (fmap not . f) =<< liftM2 ((++).maybeToList) e col
return col'
-- | A helper function equivalent to @flip maybe (return.Just)@.
maybeE :: Event a -> Maybe a -> Event a
maybeE e Nothing = e
maybeE _ jx = return jx