diff --git a/highjson.cabal b/highjson.cabal
--- a/highjson.cabal
+++ b/highjson.cabal
@@ -1,5 +1,5 @@
 name:                highjson
-version:             0.4.0.0
+version:             0.5.0.0
 synopsis:            Spec based JSON parsing/serialisation
 description:         Low boilerplate, easy to use and very fast JSON serialisation and parsing without generics or TemplateHaskell
 homepage:            https://github.com/agrafix/highjson
@@ -8,7 +8,7 @@
 license-file:        LICENSE
 author:              Alexander Thiemann <mail@athiemann.net>
 maintainer:          Alexander Thiemann <mail@athiemann.net>
-copyright:           (c) 2015 - 2017 Alexander Thiemann
+copyright:           (c) 2015 - 2021 Alexander Thiemann
 category:            Text, Web, JSON
 build-type:          Simple
 stability:           experimental
diff --git a/src/Data/HighJson.hs b/src/Data/HighJson.hs
--- a/src/Data/HighJson.hs
+++ b/src/Data/HighJson.hs
@@ -46,9 +46,11 @@
     deriving (Typeable, Eq, Show, Functor, Traversable, Foldable, Bounded)
 infixr 8 :&
 
+instance (Semigroup a, Semigroup b) => Semigroup (a :& b) where
+    (a :& b) <> (a' :& b') = (a <> a') :& (b <> b')
+
 instance (Monoid a, Monoid b) => Monoid (a :& b) where
     mempty = mempty :& mempty
-    (a :& b) `mappend` (a' :& b') = (a `mappend` a') :& (b `mappend` b')
 
 -- | A monoidal type class that respects type level lists associated to the bodies
 class CombinableContainer t where
diff --git a/src/Data/HighJson/Types.hs b/src/Data/HighJson/Types.hs
--- a/src/Data/HighJson/Types.hs
+++ b/src/Data/HighJson/Types.hs
@@ -16,11 +16,9 @@
 
 import Control.Applicative
 import Control.Lens hiding ((.=))
-import Control.Monad
 import Data.Aeson
 import Data.Aeson.Types hiding (parse)
 import Data.HVect
-import Data.Monoid
 import qualified Data.Text as T
 
 data SpecType
@@ -93,20 +91,21 @@
     case hs_bodySpec hs of
       BodySpecSum s -> object $ fst $ jsonSerSum s val
       BodySpecRecord r -> object $ fst $ jsonSerRec r val
-      BodySpecEnum e -> toJSON $ jsonSerEnum e val
+      BodySpecEnum e -> toJSON $ jsonSerEnum (hs_name hs) e val
 
 jsonEncoder :: AllHave ToJSON as => HighSpec a ty as -> a -> Encoding
 jsonEncoder hs val =
     case hs_bodySpec hs of
       BodySpecSum s -> pairs $ snd $ jsonSerSum s val
       BodySpecRecord r -> pairs $ snd $ jsonSerRec r val
-      BodySpecEnum e -> toEncoding $ jsonSerEnum e val
+      BodySpecEnum e -> toEncoding $ jsonSerEnum (hs_name hs) e val
 
-jsonSerEnum :: EnumSpec a -> a -> T.Text
-jsonSerEnum (EnumSpec opts) val =
+jsonSerEnum :: T.Text -> EnumSpec a -> a -> T.Text
+jsonSerEnum enumName (EnumSpec opts) val =
     loop opts
     where
-      loop [] = error "Empty enum spec"
+      loop [] =
+          error $ "Empty enum spec for " <> T.unpack enumName <> ". Did you mention all cases?"
       loop (x : xs) =
           case val ^? eo_prism x of
             Just () -> eo_jsonKey x
@@ -142,7 +141,7 @@
             f :+: fs ->
                 let pair = (rf_jsonKey f, toJSON $ rf_get f val)
                     encoder = rf_jsonKey f .= rf_get f val
-                in loop fs ((pair : ps), encoder <> encoding)
+                in loop fs (pair : ps, encoder <> encoding)
 
 jsonParser :: AllHave FromJSON as => HighSpec a ty as -> Value -> Parser a
 jsonParser hs =
@@ -181,11 +180,11 @@
                 "Failed to parse as " ++ T.unpack name
             o :|: os ->
                 let parse =
-                        liftM (so_prism o #) $ obj .: so_jsonKey o
+                        fmap (so_prism o #) $ obj .: so_jsonKey o
                 in parse <|> loop os
 
 
-jsonParserEnum :: Monad m => T.Text -> EnumSpec a -> T.Text -> m a
+jsonParserEnum :: (MonadFail m, Monad m) => T.Text -> EnumSpec a -> T.Text -> m a
 jsonParserEnum name (EnumSpec sopts) t =
     loop sopts
     where
