diff --git a/pipes-fluid.cabal b/pipes-fluid.cabal
--- a/pipes-fluid.cabal
+++ b/pipes-fluid.cabal
@@ -1,5 +1,5 @@
 name:                pipes-fluid
-version:             0.5.0.2
+version:             0.5.0.3
 synopsis:            Reactively combines Producers so that a value is yielded as soon as possible.
 description:         Please see README.md
 homepage:            https://github.com/louispan/pipes-fluid#readme
diff --git a/src/Pipes/Fluid/Impulse.hs b/src/Pipes/Fluid/Impulse.hs
--- a/src/Pipes/Fluid/Impulse.hs
+++ b/src/Pipes/Fluid/Impulse.hs
@@ -16,6 +16,7 @@
 import Control.Applicative
 import Control.Lens
 import Control.Monad.Trans.Class
+import Data.Semigroup
 import Data.These
 import qualified Pipes as P
 import Pipes.Fluid.Merge
@@ -28,6 +29,13 @@
     }
 
 makeWrapped ''Impulse
+
+instance  (Alternative m, Monad m, Semigroup a) => Semigroup (Impulse m a) where
+    (<>) = mergeDiscrete
+
+instance  (Alternative m, Monad m, Semigroup a) => Monoid (Impulse m a) where
+    mempty = Impulse $ pure ()
+    mappend = mergeDiscrete
 
 instance Monad m =>
          Functor (Impulse m) where
diff --git a/src/Pipes/Fluid/ImpulseIO.hs b/src/Pipes/Fluid/ImpulseIO.hs
--- a/src/Pipes/Fluid/ImpulseIO.hs
+++ b/src/Pipes/Fluid/ImpulseIO.hs
@@ -22,6 +22,7 @@
 import Control.Monad.Trans.Class
 import Control.Monad.Trans.Control
 import Data.Constraint.Forall (Forall)
+import Data.Semigroup
 import Data.These
 import qualified Pipes as P
 import Pipes.Fluid.Merge
@@ -38,6 +39,13 @@
     }
 
 makeWrapped ''ImpulseIO
+
+instance  (MonadBaseControl IO m, Forall (A.Pure m), Semigroup a) => Semigroup (ImpulseIO m a) where
+    (<>) = mergeDiscrete
+
+instance  (MonadBaseControl IO m, Forall (A.Pure m), Semigroup a) => Monoid (ImpulseIO m a) where
+    mempty = ImpulseIO $ pure ()
+    mappend = mergeDiscrete
 
 instance Monad m => Functor (ImpulseIO m) where
   fmap f (ImpulseIO as) = ImpulseIO $ as P.>-> PP.map f
diff --git a/src/Pipes/Fluid/Merge.hs b/src/Pipes/Fluid/Merge.hs
--- a/src/Pipes/Fluid/Merge.hs
+++ b/src/Pipes/Fluid/Merge.hs
@@ -4,6 +4,8 @@
 
 import qualified GHC.Generics as G
 import Data.Semigroup
+import Data.Foldable
+import qualified Data.List.NonEmpty as NE
 
 -- | Differentiates whether a value from either or both producers.
 -- In the case of one producer, additional identify if the other producer is live or dead.
@@ -98,12 +100,25 @@
 discreteBoth (Coupled FromBoth x y) = Just (x, y)
 discreteBoth _ = Nothing
 
--- | Keep only the values originated from both, replacing other yields with Nothing.
--- This is useful when React is based on STM, since filtering with Producer STM results in
--- larger STM transactions which may result in blocking.
+-- | Keep only the "new" values
+discrete' :: Merged x x -> NE.NonEmpty x
+discrete' (Coupled FromBoth x y) = x  NE.:| [y]
+discrete' (Coupled (FromRight _) _ y) = y NE.:| []
+discrete' (Coupled (FromLeft _) x _) = x NE.:| []
+discrete' (RightOnly _ y) = y NE.:| []
+discrete' (LeftOnly _ x) = x  NE.:| []
+
+-- | Keep only the "new" values (using semigroup <> when both values were active)
 discrete :: Semigroup x => Merged x x -> x
-discrete (Coupled FromBoth x y) = x <> y
-discrete (Coupled (FromRight _) _ y) = y
-discrete (Coupled (FromLeft _) x _) = x
-discrete (RightOnly _ y) = y
-discrete (LeftOnly _ x) = x
+discrete = nonEmptyFoldl1' . discrete'
+    where
+      nonEmptyFoldl1' :: Semigroup b => NE.NonEmpty b -> b
+      nonEmptyFoldl1' (x  NE.:| xs) = foldl' (<>) x xs
+
+-- | merge two producers of the same type together.
+mergeDiscrete' :: (Merge f, Functor f) => f x -> f x -> f (NE.NonEmpty x)
+mergeDiscrete' x y = discrete' <$> (x `merge` y)
+
+-- | merge two producers of the same type together (using semigroup <> when both values were active)
+mergeDiscrete :: (Semigroup x, Merge f, Functor f) => f x -> f x -> f x
+mergeDiscrete x y = discrete <$> (x `merge` y)
