reactive-banana 1.1.0.1 → 1.2.0.0
raw patch · 7 files changed
+86/−26 lines, 7 filesdep +semigroupsdep ~pqueuenew-uploaderPVP ok
version bump matches the API change (PVP)
Dependencies added: semigroups
Dependency ranges changed: pqueue
API changes (from Hackage documentation)
+ Reactive.Banana.Combinators: infixl 4 <@
- Reactive.Banana.Combinators: class Monad m => MonadMoment m
+ Reactive.Banana.Combinators: class MonadFix m => MonadMoment m
Files
- CHANGELOG.md +12/−1
- reactive-banana.cabal +6/−4
- src/Control/Monad/Trans/ReaderWriterIO.hs +4/−0
- src/Reactive/Banana/Combinators.hs +3/−3
- src/Reactive/Banana/Frameworks.hs +25/−11
- src/Reactive/Banana/Prim/Types.hs +15/−6
- src/Reactive/Banana/Types.hs +21/−1
CHANGELOG.md view
@@ -1,5 +1,16 @@-Changelog for the `reactive-banana` package+Changelog for the `reactive-banana** package -------------------------------------------++**version 1.2.0.0**++* Make `MonadFix` superclass of `MonadMoment`. [#128][]+* Add `Semigroup` and `Monoid` instances for `Event`. [#104][]+* Semigroup compatibility with GHC 8.4.1 [#168][]+* Increased upper-bound on `pqueue`.++ [#128]: https://github.com/HeinrichApfelmus/reactive-banana/pull/128+ [#104]: https://github.com/HeinrichApfelmus/reactive-banana/issues/104+ [#168]: https://github.com/HeinrichApfelmus/reactive-banana/pull/168 **version 1.1.0.1**
reactive-banana.cabal view
@@ -1,5 +1,5 @@ Name: reactive-banana-Version: 1.1.0.1+Version: 1.2.0.0 Synopsis: Library for functional reactive programming (FRP). Description: Reactive-banana is a library for Functional Reactive Programming (FRP).@@ -23,7 +23,7 @@ Author: Heinrich Apfelmus Maintainer: Heinrich Apfelmus <apfelmus quantentunnel de> Category: FRP-Cabal-version: >= 1.16+Cabal-version: >= 1.18 Build-type: Simple extra-source-files: CHANGELOG.md,@@ -42,12 +42,13 @@ hs-source-dirs: src build-depends: base >= 4.2 && < 5,+ semigroups >= 0.13 && < 0.19, containers >= 0.5 && < 0.6, transformers >= 0.2 && < 0.6, vault == 0.3.*, unordered-containers >= 0.2.1.0 && < 0.3, hashable >= 1.1 && < 1.3,- pqueue >= 1.0 && < 1.4+ pqueue >= 1.0 && < 1.5 exposed-modules: Control.Event.Handler,@@ -84,5 +85,6 @@ HUnit >= 1.2 && < 2, test-framework >= 0.6 && < 0.9, test-framework-hunit >= 0.2 && < 0.4,- reactive-banana, vault, containers, transformers,+ reactive-banana, vault, containers,+ semigroups, transformers, unordered-containers, hashable, psqueues, pqueue
src/Control/Monad/Trans/ReaderWriterIO.hs view
@@ -15,6 +15,7 @@ import Control.Monad.Trans.Class import Data.IORef import Data.Monoid+import Data.Semigroup {----------------------------------------------------------------------------- Type and class instances@@ -34,6 +35,9 @@ instance MonadFix m => MonadFix (ReaderWriterIOT r w m) where mfix = mfixR instance MonadIO m => MonadIO (ReaderWriterIOT r w m) where liftIO = liftIOR instance MonadTrans (ReaderWriterIOT r w) where lift = liftR++instance (Monad m, a ~ ()) => Semigroup (ReaderWriterIOT r w m a) where+ mx <> my = mx >> my instance (Monad m, a ~ ()) => Monoid (ReaderWriterIOT r w m a) where mempty = return ()
src/Reactive/Banana/Combinators.hs view
@@ -15,10 +15,10 @@ -- ** First-order -- | This subsections lists the primitive first-order combinators for FRP.- -- The 'Functor' and 'Applicative' instances are also part of this,+ -- The 'Functor', 'Applicative' and 'Monoid' instances are also part of this, -- but they are documented at the types 'Event' and 'Behavior'. module Control.Applicative,- module Data.Monoid,+ module Data.Semigroup, never, unionWith, filterE, apply, @@ -45,7 +45,7 @@ import Control.Applicative import Control.Monad import Data.Maybe (isJust, catMaybes)-import Data.Monoid (Monoid(..))+import Data.Semigroup import qualified Reactive.Banana.Internal.Combinators as Prim import Reactive.Banana.Types
src/Reactive/Banana/Frameworks.hs view
@@ -258,17 +258,31 @@ imposeChanges :: Behavior a -> Event () -> Behavior a imposeChanges b e = B $ Prim.imposeChanges (unB b) (Prim.mapE (const ()) (unE e)) --- | Dynamically add input and output to an existing event network.------ Note: You can even do 'IO' actions here,--- which is useful if you want to register additional event handlers--- dynamically.--- However, there is no--- guarantee about the order in which the actions are executed.--- If the result 'Event' of this function is garbage collected,--- it may also happen that the actions are not executed at all.--- If you want a reliable way to turn events into 'IO' actions--- use the 'reactimate' and 'reactimate'' functions.+{- | Dynamically add input and output to an existing event network.+++Note: You can perform 'IO' actions here, which is useful if you want+to register additional event handlers dynamically.++However, if two arguments to 'execute' occur simultaneously,+then the order in which the 'IO' therein are executed is unspecified.+For instance, in the following code++> example e = do+> e1 <- execute (liftIO (putStrLn "A") <$ e)+> e2 <- execute (liftIO (putStrLn "B") <$ e)+> return (e1,e2)++it is unspecified whether @A@ or @B@ are printed first.++Moreover, if the result 'Event' of this function has been garbage collected,+it may also happen that the actions are not executed at all.+In the example above, if the events `e1` and `e2` are not used any further,+then it can be that neither @A@ nor @B@ will be printed.++If your main goal is to reliably turn events into 'IO' actions,+use the 'reactimate' and 'reactimate'' functions instead.+-} execute :: Event (MomentIO a) -> MomentIO (Event a) execute = MIO . fmap E . Prim.executeE . Prim.mapE unMIO . unE
src/Reactive/Banana/Prim/Types.hs view
@@ -10,7 +10,8 @@ import Control.Monad.Trans.ReaderWriterIO import Data.Functor import Data.Hashable-import Data.Monoid+import Data.Monoid (Monoid, mempty, mappend)+import Data.Semigroup import qualified Data.Vault.Lazy as Lazy import System.IO.Unsafe import System.Mem.Weak@@ -51,9 +52,12 @@ -- , late build actions -- ) +instance Semigroup BuildW where+ BuildW x <> BuildW y = BuildW (x <> y)+ instance Monoid BuildW where- mempty = BuildW mempty- (BuildW x) `mappend` (BuildW y) = BuildW (x `mappend` y)+ mempty = BuildW mempty+ mappend = (<>) type BuildIO = Build @@ -70,9 +74,11 @@ -- | 'IO' actions as a monoid with respect to sequencing. newtype Action = Action { doit :: IO () }+instance Semigroup Action where+ Action x <> Action y = Action (x >> y) instance Monoid Action where mempty = Action $ return ()- (Action x) `mappend` (Action y) = Action (x >> y)+ mappend = (<>) -- | Lens-like functionality. data Lens s a = Lens (s -> a) (a -> s -> s)@@ -185,9 +191,12 @@ next :: Time -> Time next (T n) = T (n+1) +instance Semigroup Time where+ T x <> T y = T (max x y)+ instance Monoid Time where- mappend (T x) (T y) = T (max x y)- mempty = beginning+ mappend = (<>)+ mempty = beginning {----------------------------------------------------------------------------- Notes
src/Reactive/Banana/Types.hs view
@@ -8,6 +8,7 @@ Future(..), ) where +import Data.Semigroup import Control.Applicative import Control.Monad import Control.Monad.IO.Class@@ -42,7 +43,26 @@ instance Functor Event where fmap f = E . Prim.mapE f . unE +-- | The combinator '<>' merges two event streams of the same type.+-- In case of simultaneous occurrences,+-- the events are combined with the underlying 'Semigroup' operation.+-- Semantically,+--+-- > (<>) :: Event a -> Event a -> Event a+-- > (<>) ex ey = unionWith (<>) ex ey+instance Semigroup a => Semigroup (Event a) where+ x <> y = E $ Prim.unionWith (<>) (unE x) (unE y) +-- | The combinator 'mempty' represents an event that never occurs.+-- It is a synonym,+--+-- > mempty :: Event a+-- > mempty = never+instance Semigroup a => Monoid (Event a) where+ mempty = E $ Prim.never+ mappend = (<>)++ {-| @Behavior a@ represents a value that varies in time. Semantically, you can think of it as a function @@ -120,7 +140,7 @@ that happens at one particular moment in time. Unlike the 'Moment' monad, it need not be pure anymore. -}-class Monad m => MonadMoment m where+class MonadFix m => MonadMoment m where liftMoment :: Moment a -> m a instance MonadMoment Moment where liftMoment = id