diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## [0.9.0]
+### Added
+- (#59) Expose `makeMapComponents`, which creates `Component` instances with `Map` stores
+### Changed
+- (#60) Add `Component` type names in non-existent component errors
+- Relaxed the type of `modify` to allow a different return type
+- Constrain the `cmapM_` type `(c -> SystemT w m ()) -> SystemT w m ()`, to make it clearer that the inner function does not update `Components`
+- Simplify nix infrastructure
+
+## [0.8.3]
+### Changed
+- (#58) Added support for Template Haskell 2.15.0.0 through CPP flags
+
 ## [0.8.2]
 ### Changed
 - (#55) Fixed a bug where components where not properly deleted from the cache following the cache bitmasking update
diff --git a/apecs.cabal b/apecs.cabal
--- a/apecs.cabal
+++ b/apecs.cabal
@@ -1,5 +1,5 @@
 name:                apecs
-version:             0.8.3
+version:             0.9.0
 homepage:            https://github.com/jonascarpay/apecs#readme
 license:             BSD3
 license-file:        LICENSE
diff --git a/src/Apecs/Stores.hs b/src/Apecs/Stores.hs
--- a/src/Apecs/Stores.hs
+++ b/src/Apecs/Stores.hs
@@ -22,6 +22,7 @@
 import           Data.IORef
 import           Data.Proxy
 import           Data.Bits (shiftL, (.&.))
+import           Data.Typeable (Typeable, typeRep)
 import qualified Data.Vector.Mutable         as VM
 import qualified Data.Vector.Unboxed         as U
 import qualified Data.Vector.Unboxed.Mutable as UM
@@ -36,11 +37,16 @@
 instance MonadIO m => ExplInit m (Map c) where
   explInit = liftIO$ Map <$> newIORef mempty
 
-instance MonadIO m => ExplGet m (Map c) where
+instance (MonadIO m, Typeable c) => ExplGet m (Map c) where
   explExists (Map ref) ety = liftIO$ M.member ety <$> readIORef ref
   explGet    (Map ref) ety = liftIO$ flip fmap (M.lookup ety <$> readIORef ref) $ \case
     Just c -> c
-    Nothing -> error $ "Reading non-existant Map component for entity " <> show ety
+    notFound -> error $ unwords
+      [ "Reading non-existent Map component"
+      , show (typeRep notFound)
+      , "for entity"
+      , show ety
+      ]
   {-# INLINE explExists #-}
   {-# INLINE explGet #-}
 
@@ -66,11 +72,15 @@
 instance MonadIO m => ExplInit m (Unique c) where
   explInit = liftIO$ Unique <$> newIORef Nothing
 
-instance MonadIO m => ExplGet m (Unique c) where
+instance (MonadIO m, Typeable c) => ExplGet m (Unique c) where
   {-# INLINE explGet #-}
   explGet (Unique ref) _ = liftIO$ flip fmap (readIORef ref) $ \case
     Just (_, c)  -> c
-    Nothing -> error $ "Reading non-existant Unique component"
+    notFound -> error $ unwords
+      [ "Reading non-existent Unique component"
+      , show (typeRep notFound)
+      ]
+
   {-# INLINE explExists #-}
   explExists (Unique ref) ety = liftIO$ maybe False ((==ety) . fst) <$> readIORef ref
 
diff --git a/src/Apecs/System.hs b/src/Apecs/System.hs
--- a/src/Apecs/System.hs
+++ b/src/Apecs/System.hs
@@ -57,12 +57,13 @@
 
 -- | Applies a function, if possible.
 {-# INLINE modify #-}
-modify, ($~) :: forall w m c. (Get w m c, Set w m c) => Entity -> (c -> c) -> SystemT w m ()
+modify, ($~) :: forall w m cx cy. (Get w m cx, Set w m cy) => Entity -> (cx -> cy) -> SystemT w m ()
 modify (Entity ety) f = do
-  s :: Storage c <- getStore
+  sx :: Storage cx <- getStore
+  sy :: Storage cy <- getStore
   lift$ do
-    x <- explGet s ety
-    explSet s ety (f x)
+    x <- explGet sx ety
+    explSet sy ety (f x)
 
 -- | @modify@ operator
 ($~) = modify
@@ -119,8 +120,8 @@
 
 -- | Monadically iterates over all entites with a @cx@
 {-# INLINE cmapM_ #-}
-cmapM_ :: forall w m c a. (Get w m c, Members w m c)
-       => (c -> SystemT w m a) -> SystemT w m ()
+cmapM_ :: forall w m c. (Get w m c, Members w m c)
+       => (c -> SystemT w m ()) -> SystemT w m ()
 cmapM_ sys = do
   s :: Storage c <- getStore
   sl <- lift$ explMembers s
diff --git a/src/Apecs/TH.hs b/src/Apecs/TH.hs
--- a/src/Apecs/TH.hs
+++ b/src/Apecs/TH.hs
@@ -2,7 +2,10 @@
 {-# LANGUAGE TypeFamilies    #-}
 
 module Apecs.TH
-  ( makeWorld, makeWorldNoEC, makeWorldAndComponents
+  ( makeWorld
+  , makeWorldNoEC
+  , makeWorldAndComponents
+  , makeMapComponents
   ) where
 
 import Control.Monad
@@ -49,16 +52,20 @@
 
   return $ wldDecl : initSig : initDecl : hasDecl
 
-makeComponent :: Name -> Q Dec
-makeComponent comp = do
+-- | Creates 'Component' instances with 'Map' stores
+makeMapComponents :: [Name] -> Q [Dec]
+makeMapComponents = mapM makeMapComponent
+
+makeMapComponent :: Name -> Q Dec
+makeMapComponent comp = do
   let ct = return$ ConT comp
   head <$> [d| instance Component $ct where type Storage $ct = Map $ct |]
 
--- | Same as makeWorld, but also defines @Component@ instances with a @Map@ store.
+-- | Calls 'makeWorld' and 'makeMapComponents', i.e. makes a world and also defines @Component@ instances with a @Map@ store.
 makeWorldAndComponents :: String -> [Name] -> Q [Dec]
 makeWorldAndComponents worldName cTypes = do
   wdecls <- makeWorld worldName cTypes
-  cdecls <- mapM makeComponent cTypes
+  cdecls <- makeMapComponents cTypes
   return $ wdecls ++ cdecls
 
 {-|
