diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -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**
 
diff --git a/reactive-banana.cabal b/reactive-banana.cabal
--- a/reactive-banana.cabal
+++ b/reactive-banana.cabal
@@ -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
diff --git a/src/Control/Monad/Trans/ReaderWriterIO.hs b/src/Control/Monad/Trans/ReaderWriterIO.hs
--- a/src/Control/Monad/Trans/ReaderWriterIO.hs
+++ b/src/Control/Monad/Trans/ReaderWriterIO.hs
@@ -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 ()
diff --git a/src/Reactive/Banana/Combinators.hs b/src/Reactive/Banana/Combinators.hs
--- a/src/Reactive/Banana/Combinators.hs
+++ b/src/Reactive/Banana/Combinators.hs
@@ -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
diff --git a/src/Reactive/Banana/Frameworks.hs b/src/Reactive/Banana/Frameworks.hs
--- a/src/Reactive/Banana/Frameworks.hs
+++ b/src/Reactive/Banana/Frameworks.hs
@@ -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
 
diff --git a/src/Reactive/Banana/Prim/Types.hs b/src/Reactive/Banana/Prim/Types.hs
--- a/src/Reactive/Banana/Prim/Types.hs
+++ b/src/Reactive/Banana/Prim/Types.hs
@@ -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
diff --git a/src/Reactive/Banana/Types.hs b/src/Reactive/Banana/Types.hs
--- a/src/Reactive/Banana/Types.hs
+++ b/src/Reactive/Banana/Types.hs
@@ -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
