reactive-banana-0.8.0.0: src/Reactive/Banana/Types.hs
{-----------------------------------------------------------------------------
reactive-banana
------------------------------------------------------------------------------}
module Reactive.Banana.Types (
-- | Primitive types.
Event (..), Behavior (..), Moment (..), Future(..)
) where
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Fix
import qualified Reactive.Banana.Internal.Combinators as Prim
import Reactive.Banana.Internal.Phantom
{-| @Event t a@ represents a stream of events as they occur in time.
Semantically, you can think of @Event t a@ as an infinite list of values
that are tagged with their corresponding time of occurence,
> type Event t a = [(Time,a)]
-}
newtype Event t a = E { unE :: Prim.Event [a] }
{-| @Behavior t a@ represents a value that varies in time. Think of it as
> type Behavior t a = Time -> a
-}
newtype Behavior t a = B { unB :: Prim.Behavior a }
-- | The 'Future' monad is just a helper type for the 'changes' function.
--
-- A value of type @Future a@ is only available in the context
-- of a 'reactimate' but not during event processing.
newtype Future a = F { unF :: Prim.Future a }
-- boilerplate class instances
instance Functor Future where fmap f = F . fmap f . unF
instance Monad Future where
return = F . return
m >>= g = F $ unF m >>= unF . g
instance Applicative Future where
pure = F . pure
f <*> a = F $ unF f <*> unF a
{-| The 'Moment' monad denotes a value at a particular /moment in time/.
This monad is not very interesting, it is mainly used for book-keeping.
In particular, the type parameter @t@ is used
to disallow various unhealthy programs.
This monad is also used to describe event networks
in the "Reactive.Banana.Frameworks" module.
This only happens when the type parameter @t@
is constrained by the 'Frameworks' class.
To be precise, an expression of type @Moment t a@ denotes
a value of type @a@ that is observed at a moment in time
which is indicated by the type parameter @t@.
-}
newtype Moment t a = M { unM :: Prim.Moment a }
-- boilerplate class instances
instance Functor (Moment t) where fmap f = M . fmap f . unM
instance Monad (Moment t) where
return = M . return
m >>= g = M $ unM m >>= unM . g
instance Applicative (Moment t) where
pure = M . pure
f <*> a = M $ unM f <*> unM a
instance MonadFix (Moment t) where mfix f = M $ mfix (unM . f)
instance Frameworks t => MonadIO (Moment t) where
liftIO = M . Prim.liftIONow