{----------------------------------------------------------------------------- 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