diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,3 +1,8 @@
+0.1.0.4
+
+* Fix `Semigroup` instance.
+* Implement `Monoid` instance.
+
 0.1.0.3
 
 * Fix bug in `Extend` instance.
diff --git a/exitcode.cabal b/exitcode.cabal
--- a/exitcode.cabal
+++ b/exitcode.cabal
@@ -1,7 +1,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                exitcode
-version:             0.1.0.3
+version:             0.1.0.4
 synopsis:            Monad transformer for exit codes
 description:
   <<https://system-f.gitlab.io/logo/systemf-450x450.jpg>>
diff --git a/src/Control/Exitcode.hs b/src/Control/Exitcode.hs
--- a/src/Control/Exitcode.hs
+++ b/src/Control/Exitcode.hs
@@ -16,10 +16,9 @@
 , exitsuccess
 , exitsuccess0
 , exitfailure0
+, exitCodeValue
 , fromExitCode
 , fromExitCode'
-, fromExitCodeValue
-, fromExitCodeValue'
 -- * Extraction
 , runExitcode
 -- * Optics
@@ -73,6 +72,7 @@
 import Data.Functor.Identity ( Identity(Identity) )
 import Data.Int ( Int )
 import Data.Maybe ( Maybe(Nothing, Just), fromMaybe )
+import Data.Monoid hiding (Alt)
 import Data.Ord ( Ord(compare) )
 import Data.Semigroup ( Semigroup((<>)) )
 import Data.Traversable ( Traversable(traverse) )
@@ -80,6 +80,10 @@
 import GHC.Show ( Show(showsPrec) )
 import System.Exit ( ExitCode(..) )
 
+-- $setup
+-- >>> import Prelude
+-- >>> import Control.Lens
+
 -- | An exit code status where failing with a value `0` cannot be represented.
 --
 -- Transformer for either a non-zero exit code (`Int`) or a value :: `a`.
@@ -122,17 +126,33 @@
 --
 -- >>> exitfailure0 99 :: ExitcodeT0 Identity
 -- ExitcodeT (Identity (Left 99))
+-- >>> exitsuccess "abc" <> exitCodeValue 99 "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "abc"))
+-- >>> exitCodeValue 99 "abc" <> exitsuccess "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "def"))
+-- >>> exitCodeValue 99 "abc" <> exitCodeValue 88 "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Left 88))
 exitfailure0 ::
   Applicative f =>
   Int
   -> ExitcodeT0 f
 exitfailure0 n =
-  if n == 0
-    then
-      exitsuccess0
-    else
-      ExitcodeT . pure . Left $ n
+  exitCodeValue n ()
 
+-- |
+--
+-- >>> exitCodeValue 99 "abc" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Left 99))
+-- >>> exitCodeValue 0 "abc" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "abc"))
+exitCodeValue ::
+  Applicative f =>
+  Int
+  -> a
+  -> ExitcodeT f a
+exitCodeValue n a =
+  ExitcodeT (pure (bool (Left n) (Right a) (n == 0)))
+
 -- | From base exitcode.
 --
 -- >>> fromExitCode (Identity ExitSuccess)
@@ -161,27 +181,6 @@
 fromExitCode' =
   fromExitCode . Identity
 
--- |
---
--- >>> fromExitCodeValue 99 "abc" :: ExitcodeT Identity String
--- ExitcodeT (Identity (Left 99))
--- >>> fromExitCodeValue 0 "abc" :: ExitcodeT Identity String
--- ExitcodeT (Identity (Right "abc"))
-fromExitCodeValue ::
-  Applicative f =>
-  Int
-  -> a
-  -> ExitcodeT f a
-fromExitCodeValue n a =
-  ExitcodeT (pure (bool (Left n) (Right a) (n == 0)))
-
-fromExitCodeValue' ::
-  Applicative f =>
-  Int
-  -> ExitcodeT0 f
-fromExitCodeValue' n =
-  fromExitCodeValue n ()
-
 -- | Isomorphism from base exitcode to underlying `Maybe (Either Int ())` where `Int` is non-zero.
 --
 -- >>> view exitCode (Identity (ExitFailure 99))
@@ -236,6 +235,8 @@
 -- Nothing
 -- >>> review _ExitFailure 99
 -- ExitcodeT (Identity (Left 99))
+-- >>> review _ExitFailure 0
+-- ExitcodeT (Identity (Right ()))
 _ExitFailure ::
   Prism'
     Exitcode0
@@ -282,15 +283,15 @@
 
 -- |
 --
--- >>> exitsuccess "abc" >>= \s -> exitsuccess (reverse s) :: ExitcodeT Identity String
+-- >>> exitsuccess "abc" >>- \s -> exitsuccess (reverse s) :: ExitcodeT Identity String
 -- ExitcodeT (Identity (Right "cba"))
--- >>> exitsuccess "abc" >>= \_ -> exitfailure0 99 :: ExitcodeT Identity ()
+-- >>> exitsuccess "abc" >>- \_ -> exitfailure0 99 :: ExitcodeT Identity ()
 -- ExitcodeT (Identity (Left 99))
--- >>> exitfailure0 99 >>= \_ -> exitsuccess "abc" :: ExitcodeT Identity String
+-- >>> exitfailure0 99 >>- \_ -> exitsuccess "abc" :: ExitcodeT Identity String
 -- ExitcodeT (Identity (Left 99))
--- >>> exitfailure0 99 >>= \_ -> exitfailure0 88 :: ExitcodeT Identity ()
+-- >>> exitfailure0 99 >>- \_ -> exitfailure0 88 :: ExitcodeT Identity ()
 -- ExitcodeT (Identity (Left 99))
--- >>> let loop = loop in exitfailure0 99 >>= loop :: ExitcodeT Identity ()
+-- >>> let loop = loop in exitfailure0 99 >>- loop :: ExitcodeT Identity ()
 -- ExitcodeT (Identity (Left 99))
 instance Monad f => Bind (ExitcodeT f) where
   (>>-) =
@@ -307,12 +308,33 @@
   ExitcodeT a <!> ExitcodeT b =
     ExitcodeT (a >>= either (const b) (pure a))
 
-instance Monad f => Semigroup (ExitcodeT f a) where
+-- |
+--
+-- >>> exitsuccess "abc" <> exitsuccess "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "abcdef"))
+-- >>> exitsuccess "abc" <> exitCodeValue 99 "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "abc"))
+-- >>> exitCodeValue 99 "abc" <> exitsuccess "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right "def"))
+-- >>> exitCodeValue 99 "abc" <> exitCodeValue 88 "def" :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Left 88))
+instance (Semigroup a, Applicative f) => Semigroup (ExitcodeT f a) where
   ExitcodeT a <> ExitcodeT b =
-    ExitcodeT (a >>= either (const b) (pure a))
+    let jn (Left _) x  = x
+        jn x (Left _) = x
+        jn (Right a1) (Right a2) = Right (a1 <> a2)
+    in  ExitcodeT (liftA2 jn a b)
 
 -- |
 --
+-- >>> mempty :: ExitcodeT Identity String
+-- ExitcodeT (Identity (Right ""))
+instance (Monoid a, Applicative f) => Monoid (ExitcodeT f a) where
+  mempty =
+    ExitcodeT (pure (Right mempty))
+
+-- |
+--
 -- >>> duplicated (exitfailure0 99) :: ExitcodeT Identity (ExitcodeT Identity ())
 -- ExitcodeT (Identity (Right (ExitcodeT (Identity (Left 99)))))
 -- >>> duplicated (exitsuccess "abc") :: ExitcodeT Identity (ExitcodeT Identity String)
@@ -382,7 +404,7 @@
 
 -- |
 --
--- >>> writer'' ('x', "abc")
+-- >>> writer ('x', "abc") :: ExitcodeT ((,) String) Char
 -- ExitcodeT ("abc",Right 'x')
 -- >>> listen (exitfailure0 99 :: ExitcodeT ((,) String) ())
 -- ExitcodeT ("",Left 99)
