-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Monadic FRP -- -- FRP style where sequential composition (switching) is more primitive -- than in other approaches. @package drClickOn @version 0.1 -- | Monadic FRP basic definitions and composition functions. -- -- See the paper Monadic Functional Reactive Programming by Atze -- van der Ploeg. Haskell Symposium '13. -- http://homepages.cwi.nl/~ploeg/papers/monfrp.pdf. -- -- An example can be found at -- https://github.com/cwi-swat/monadic-frp. -- -- Notice that currently Monadic FRP relies on a closed union (ADT) of -- basic events, which has the following downsides: -- -- -- -- A function preprended with i indices a initialized signal variant of -- an signal computation function. module Control.MonadicFRP data Event a Request :: Event a Occurred :: a -> Event a -- | An alias for a set of event requests type EvReqs e = Set e -- | An alias for a set of event occurances type EvOccs e = Set e -- | A reactive computation data React e alpha Done :: alpha -> React e alpha Await :: (EvReqs e) -> (EvOccs e -> React e alpha) -> React e alpha -- | Request a single event exper :: e -> React e e -- | The interpreter for reactive computations. The first argument is a -- function that answers event requests in the monad m, the second is the -- reactive computation. interpret :: Monad m => (EvReqs e -> m (EvOccs e)) -> React e a -> m a -- | A signal computation is a reactive computation of an initialized -- signal newtype Sig e a b Sig :: (React e (ISig e a b)) -> Sig e a b -- | An initialized signal data ISig e a b (:|) :: a -> (Sig e a b) -> ISig e a b End :: b -> ISig e a b -- | The interpreter for signal computations taking three arguments: -- -- interpretSig :: Monad m => (EvReqs e -> m (EvOccs e)) -> (a -> m r) -> Sig e a b -> m b -- | Run two reactive computations in parallel until either completes, and -- return the new state of both. -- -- Notice that flip first == first first :: Ord e => React e a -> React e b -> React e (React e a, React e b) -- | Alias for first parR :: Ord e => React e a -> React e b -> React e (React e a, React e b) -- | Call the continuation function of a reactive computation if it awaits -- at least one of the event occurences. update :: Ord e => React e a -> EvOccs e -> React e a -- | Repeat the given reactive computation indefinitely, each time emitting -- its result. repeat :: React e a -> Sig e a b -- | Repeat the given signal computation indefinitely, each time emitting -- its initialized signal result. spawn :: Sig e t t1 -> Sig e (ISig e t t1) b -- | Transform the emmited values of a signal computation by applying the -- function to each of them. map :: (t -> a) -> Sig e t b -> Sig e a b -- | Transform the emmited values of an initialized signal computation by -- applying the function to each of them. imap :: (t -> a) -> ISig e t b -> ISig e a b -- | The list function scanl is similar to foldl, but returns a list of -- successive reduced values instead of a single value. the signal -- variant works analogously. scanl :: (a -> t -> a) -> a -> Sig e t t1 -> Sig e a t1 iscanl :: (a -> t -> a) -> a -> Sig e t t1 -> ISig e a t1 -- | Run the signal computation as long as the given predicate does not -- hold on the emitted values. Once a value is emmited on which the -- predicate holds, the rest of the signal computation is returned. break :: (a -> Bool) -> Sig e a b -> Sig e a (ISig e a b) ibreak :: (a -> Bool) -> ISig e a b -> ISig e a (ISig e a b) -- | |foldl| on signal computations behaves the same as waiting for the -- signal computation to end and then applying the fold on the -- list of emitted values. foldl :: (a -> b -> a) -> a -> Sig e b r -> React e a ifoldl :: (a -> b -> a) -> a -> ISig e b r -> React e a -- | Find the first emmited value on which the predicate hold. find :: (a -> Bool) -> Sig t a t1 -> React t (Maybe a) -- | Sample the form of the signal computation at the time the reactive -- computation completes at :: Ord t => Sig t a t1 -> React t b -> React t (Maybe a) -- | Run the signal computation until the reactive computation completes, -- and return the new state of both computations. until :: Ord e => Sig e a t -> React e b -> Sig e a (Sig e a t, React e b) iuntil :: Ord t => ISig t a b -> React t alpha -> ISig t a (ISig t a b, React t alpha) -- | Apply the values from the second signal computation to the values from -- the first signal computation over time. When one ends, the new state -- of both is returned. (<^>) :: Ord e => Sig e (t -> a) b -> Sig e t t1 -> Sig e a (ISig e (t -> a) b, ISig e t t1) -- | Emitted the pairs of the emitted values from both signal computations -- over time. When one ends, the new state of both is returned. pairs :: Ord e => ISig e t1 b -> ISig e t2 t -> ISig e (t1, t2) (ISig e t1 b, ISig e t2 t) -- | Wait for both signal computation to become initialized, and then -- return both their initizialized signals. bothStart :: Ord t4 => Sig t4 t t1 -> Sig t4 t2 t3 -> React t4 (ISig t4 t t1, ISig t4 t2 t3) -- | Sample the former signal computation each time the later emits a -- value. indexBy :: (Show a, Ord e) => Sig e a l -> Sig e b r -> Sig e a () iindexBy :: Ord e => ISig e a b -> Sig e t t1 -> Sig e a () -- | Convert a initialized signal to a signal computation emitAll :: ISig e a b -> Sig e a b -- | Emit a single value in the signal computation mondad emit :: a -> Sig e a () -- | A signal that alway has the given form. always :: a -> Sig e a b -- | Convert a reactive computation to a signal computation. waitFor :: React e b -> Sig e a b -- | The reactive computation that never completes. hold :: Sig e a b -- | Convert the result of a signal computation to a reactive computation. res :: Sig t t1 b -> React t b -- | Convert the result of an initialized signal a reactive computation. ires :: ISig t t1 b -> React t b -- | Give the current value of a signal computation, if any. cur :: Sig t a t1 -> Maybe a -- | the head of an initalized signal, if any. icur :: ISig t a t1 -> Maybe a -- | Return the result of a reactive computation if it is done done :: React t a -> Maybe a -- | Version of done that throws an error if it the result is not -- done. done' :: React t c -> c -- | Cons the values from the first signal computation to the values form -- the latter signal computation over time. cons :: Ord e => ISig e a l -> ISig e [a] r -> ISig e [a] () -- | Run the initialized signals from the given signal computation in -- parallel, and emit the lists of the current form of all alive -- initialized signals. parList :: Ord e => Sig e (ISig e a l) r -> Sig e [a] () iparList :: Ord e => Sig e (ISig e a l) r -> ISig e [a] () -- | Memoize the continuation function of the reactive computation, and the -- continuation function of all next states. memo :: Ord e => React e a -> React e a -- | Memoize the reactive computation of the initialized signal, and -- memoize the signal computation of the tail (if any). memoSig :: Ord e => Sig e a b -> Sig e a b imemoSig :: Ord e => ISig e a b -> ISig e a b instance Show a => Show (Event a) instance Functor (React e) instance Monad (ISig e a) instance Monad (Sig e a) instance Functor (Sig e a) instance Ord a => Eq (Event a) instance Ord a => Ord (Event a) instance Monad (React e)