diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,15 +1,15 @@
 # apecs
 [![Build Status](https://travis-ci.org/jonascarpay/apecs.svg?branch=master)](https://travis-ci.org/jonascarpay/apecs)
 [![Hackage](https://img.shields.io/hackage/v/apecs.svg)](https://hackage.haskell.org/package/apecs)
-[![apecs on Stackage LTS 11](http://stackage.org/package/apecs/badge/lts-11)](http://stackage.org/lts-10/package/apecs)
+[![Stackage](https://www.stackage.org/package/apecs/badge/lts?label=Stackage)](https://www.stackage.org/package/apecs)
 
-apecs is an _Entity Component System_ framework inspired by [specs](https://github.com/slide-rs/specs) and [Entitas](https://github.com/sschmid/Entitas-CSharp).
-The front-end DSL allows you to concisely express your game logic, with an efficient back-end storage framework that can be extended to meet any performance needs.
+apecs is an _Entity Component System_ (ECS) framework inspired by [specs](https://github.com/slide-rs/specs) and [Entitas](https://github.com/sschmid/Entitas-CSharp).
+The front-end DSL uses a small set of combinators to concisely express game logic, which then translate to fast primitive operations on back-end stores.
+Both the DSL and storage framework can easily be extended to meet any performance/expressivity needs.
 
 #### Links
 - [documentation](https://hackage.haskell.org/package/apecs/docs/Apecs.html)
-- [introductory tutorial](https://github.com/jonascarpay/apecs/blob/master/tutorials/RTS.md)
-- [performance guide](https://github.com/jonascarpay/apecs/blob/master/tutorials/GoingFast.md)
+- [manual](https://github.com/jonascarpay/apecs/blob/master/prepub.pdf) (see [#19](https://github.com/jonascarpay/apecs/issues/19))
 - [apecs-physics](https://github.com/jonascarpay/apecs-physics)
 
 #### Performance
@@ -22,9 +22,7 @@
 {-# LANGUAGE DataKinds, ScopedTypeVariables, TypeFamilies, MultiParamTypeClasses, TemplateHaskell #-}
 
 import Apecs
-import Apecs.Stores
-import Apecs.Core
-import Linear
+import Linear (V2 (..))
 
 newtype Position = Position (V2 Double) deriving Show
 -- To declare a component, we need to specify how to store it
diff --git a/apecs.cabal b/apecs.cabal
--- a/apecs.cabal
+++ b/apecs.cabal
@@ -1,5 +1,5 @@
 name:                apecs
-version:             0.4.0.1
+version:             0.4.1.0
 homepage:            https://github.com/jonascarpay/apecs#readme
 license:             BSD3
 license-file:        LICENSE
@@ -9,8 +9,9 @@
 build-type:          Simple
 cabal-version:       >=1.10
 extra-source-files:  README.md
-synopsis:            A fast ECS for game engine programming
-description:         A fast ECS for game engine programming
+synopsis:            Fast ECS framework for game programming
+description:
+  Apecs is an Entity Component System framework, suitable for high-performance game programming.
 
 source-repository head
   type:     git
@@ -78,7 +79,9 @@
   ghc-options:
     -Wall
     -Odph
-    -fllvm
+    -- LLVM is disabled by default for travis/compatibility reasons
+    -- For serious benchmarks, please run with -fllvm
+    -- -fllvm
     -optlo-O3
     -threaded
     -funfolding-use-threshold1000
diff --git a/src/Apecs/Core.hs b/src/Apecs/Core.hs
--- a/src/Apecs/Core.hs
+++ b/src/Apecs/Core.hs
@@ -17,45 +17,56 @@
 import qualified Apecs.THTuples        as T
 
 -- | An Entity is just an integer, used to index into a component store.
+--   In general, use @newEntity@, @cmap@, and component tags instead of manipulating these directly.
+--   
+--   For performance reasons, negative values like (-1) are reserved for stores to represent special values, so avoid using these.
 newtype Entity = Entity {unEntity :: Int} deriving (Num, Eq, Ord, Show)
 
 -- | A System is a newtype around `ReaderT w IO a`, where `w` is the game world variable.
+--   Systems mainly serve to
+--   
+--   * Lift side effects into the IO Monad.
+--
+--   * Allow type-based lookup of a component's store through @getStore@.
 newtype System w a = System {unSystem :: ReaderT w IO a} deriving (Functor, Monad, Applicative, MonadIO)
 
--- | A component is defined by the type of its storage
---   The storage in turn supplies runtime types for the component.
---   For the component to be valid, its Storage must be an instance of Store.
+-- | A component is defined by specifying how it is stored.
+--   The constraint ensures that stores and components are mapped one-to-one.
 class (Elem (Storage c) ~ c) => Component c where
   type Storage c
 
--- | A world `Has` a component if it can produce its Storage
+-- | @Has w c@ means that world @w@ can produce a @Storage c@.
 class Component c => Has w c where
   getStore :: System w (Storage c)
 
--- | The type of components stored by a Store
+-- | The type of components stored by a store, e.g. @Elem (Map c) = c@.
 type family Elem s
 
--- | Holds components indexed by entities
+-- | Indicates that the store @s@ can be initialized.
+--   Generally, \"base\" stores like @Map c@ can be initialized, but composite stores like @MaybeStore s@ cannot.
 class ExplInit s where
-  -- | Initialize the store with its initialization arguments.
+  -- | Initialize a new empty store.
   explInit :: IO s
 
--- | Stores that support @get@ and @exists@ in the IO monad
---   If @existsIO@
+-- | Stores that we can read using @explGet@ and @explExists@.
+--   For some entity @e@, @eplGet s e@ is only guaranteed to be safe if @explExists s e@ returns @True@.
 class ExplGet s where
-  -- | Reads a component from the store. What happens if the component does not exist is left undefined.
+  -- | Reads a component from the store. What happens if the component does not exist is left undefined, and might not necessarily crash.
   explGet :: s -> Int -> IO (Elem s)
-  -- | Returns whether there is a component for the given index
+  -- | Returns whether there is a component for the given index.
   explExists :: s -> Int -> IO Bool
 
+-- | Stores that can be written.
 class ExplSet s where
-  -- | Writes a component
+  -- | Writes a component to the store.
   explSet :: s -> Int -> Elem s -> IO ()
 
+-- | Stores that components can be removed from.
 class ExplDestroy s where
   -- | Destroys the component for a given index.
   explDestroy :: s -> Int -> IO ()
 
+-- | Stores that we can request a list of member entities for.
 class ExplMembers s where
   -- | Returns an unboxed vector of member indices
   explMembers :: s -> IO (U.Vector Int)
@@ -65,6 +76,7 @@
 type Members w c = (Has w c, ExplMembers (Storage c))
 type Destroy w c = (Has w c, ExplDestroy (Storage c))
 
+-- | Identity component/store. @Identity c@ is equivalent to @c@, so using it is mostly useless.
 instance Component c => Component (Identity c) where
   type Storage (Identity c) = Identity (Storage c)
 
@@ -84,14 +96,14 @@
 instance ExplDestroy s => ExplDestroy (Identity s) where
   explDestroy (Identity s) = explDestroy s
 
--- Tuple Instances TODO
 T.makeInstances [2..8]
 
-
 -- | Psuedocomponent indicating the absence of @a@.
+--   Mainly used as e.g. @cmap $ \(a, Not b) -> c@ to iterate over entities with an @a@ but no @b@.
+--   Can also be used to delete components, like @cmap $ \a -> (Not :: Not a)@ to delete every @a@ component.
 data Not a = Not
 
--- | Pseudostore used to produce values of type @Not a@
+-- | Pseudostore used to produce values of type @Not a@, inverts @explExists@, and destroys instead of @explSet@.
 newtype NotStore s = NotStore s
 
 instance Component c => Component (Not c) where
@@ -109,7 +121,9 @@
 instance ExplDestroy s => ExplSet (NotStore s) where
   explSet (NotStore sa) ety _ = explDestroy sa ety
 
--- | Pseudostore used to produce values of type @Maybe a@
+-- | Pseudostore used to produce values of type @Maybe a@.
+--   Will always return @True@ for @explExists@.
+--   Writing can both set and delete a component using @Just@ and @Nothing@ respectively.
 newtype MaybeStore s = MaybeStore s
 instance Component c => Component (Maybe c) where
   type Storage (Maybe c) = MaybeStore (Storage c)
@@ -130,7 +144,51 @@
   explSet (MaybeStore sa) ety Nothing  = explDestroy sa ety
   explSet (MaybeStore sa) ety (Just x) = explSet sa ety x
 
+-- | Used for 'Either', a logical disjunction between two components.
+--   As expected, Either is used to model error values.
+-- Getting an @Either a b@ will first attempt to get a @b@ and return it as @Right b@, or if it does not exist, get an @a@ as @Left a@.
+-- Can also be used to set one of two things.
+data EitherStore sa sb = EitherStore sa sb
+instance (Component ca, Component cb) => Component (Either ca cb) where
+  type Storage (Either ca cb) = EitherStore (Storage ca) (Storage cb)
+
+instance (Has w ca, Has w cb) => Has w (Either ca cb) where
+  getStore = EitherStore <$> getStore <*> getStore
+
+type instance Elem (EitherStore sa sb) = Either (Elem sa) (Elem sb)
+
+instance (ExplGet sa, ExplGet sb) => ExplGet (EitherStore sa sb) where
+  explGet (EitherStore sa sb) ety = do
+    e <- explExists sb ety
+    if e then Right <$> explGet sb ety
+         else Left <$> explGet sa ety
+  explExists (EitherStore sa sb) ety = do
+    e <- explExists sb ety
+    if e then return True
+         else explExists sa ety
+
+instance (ExplSet sa, ExplSet sb) => ExplSet (EitherStore sa sb) where
+  explSet (EitherStore _ sb) ety (Right b) = explSet sb ety b
+  explSet (EitherStore sa _) ety (Left a)  = explSet sa ety a
+
+instance Component () where
+  type Storage () = ()
+type instance Elem () = ()
+instance ExplGet () where
+  explExists _ _ = return True
+  explGet _ _ = return ()
+instance ExplSet () where
+  explSet _ _ _ = return ()
+instance ExplDestroy () where
+  explDestroy _ _ = return ()
+
+-- | Pseudocomponent that functions normally for @explExists@ and @explMembers@, but always return @Filter@ for @explGet@.
+--   Can be used in cmap as @cmap $ \(Filter :: Filter a) -> b@.
+--   Since the above can be written more consicely as @cmap $ \(_ :: a) -> b@, it is rarely directly.
+--   More interestingly, we can define reusable filters like @movables = Filter :: Filter (Position, Velocity)@.
 data Filter c = Filter deriving (Eq, Show)
+
+-- Pseudostore for 'Filter'.
 newtype FilterStore s = FilterStore s
 
 instance Component c => Component (Filter c) where
@@ -145,7 +203,12 @@
   explGet _ _ = return Filter
   explExists (FilterStore s) ety = explExists s ety
 
--- | Pseudostore used to produce components of type @Entity@
+instance ExplMembers s => ExplMembers (FilterStore s) where
+  explMembers (FilterStore s) = explMembers s
+
+-- | Pseudostore used to produce components of type 'Entity'.
+-- Always returns @True@ for @explExists@, and echoes back the entity argument for @explGet@.
+-- Used in e.g. @cmap $ \(a, ety :: Entity) -> b@ to access the current entity.
 data EntityStore = EntityStore
 instance Component Entity where
   type Storage Entity = EntityStore
diff --git a/src/Apecs/Stores.hs b/src/Apecs/Stores.hs
--- a/src/Apecs/Stores.hs
+++ b/src/Apecs/Stores.hs
@@ -1,4 +1,5 @@
 {-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE LambdaCase            #-}
 {-# LANGUAGE FlexibleContexts      #-}
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE KindSignatures        #-}
@@ -54,35 +55,37 @@
 -- | A Unique contains zero or one component.
 --   Writing to it overwrites both the previous component and its owner.
 --   Its main purpose is to be a @Map@ optimized for when only ever one component inhabits it.
-data Unique c = Unique (IORef Int) (IORef c)
+data Unique c = Unique (IORef (Maybe (Int, c)))
 type instance Elem (Unique c) = c
 instance ExplInit (Unique c) where
-  explInit = Unique <$> newIORef (-1) <*> newIORef (error "Uninitialized Unique value")
+  explInit = Unique <$> newIORef Nothing
 
 instance ExplGet (Unique c) where
   {-# INLINE explGet #-}
-  explGet (Unique _ cref) _ = readIORef cref
+  explGet (Unique ref) _ = readIORef ref >>= return . \case
+    Nothing -> error "Reading empty Unique"
+    Just (_, c)  -> c
   {-# INLINE explExists #-}
-  explExists (Unique eref _) ety = (==ety) <$> readIORef eref
+  explExists (Unique ref) ety = maybe False ((==ety) . fst) <$> readIORef ref
 
 instance ExplSet (Unique c) where
   {-# INLINE explSet #-}
-  explSet (Unique eref cref) ety x = writeIORef eref ety >> writeIORef cref x
+  explSet (Unique ref) ety c = writeIORef ref (Just (ety, c))
 
 instance ExplDestroy (Unique c) where
   {-# INLINE explDestroy #-}
-  explDestroy (Unique eref _) ety = do e <- readIORef eref; when (e==ety) (writeIORef eref (-1))
+  explDestroy (Unique ref) ety = writeIORef ref Nothing
 
 instance ExplMembers (Unique c) where
   {-# INLINE explMembers #-}
-  explMembers (Unique eref _) = f <$> readIORef eref
-    where f (-1) = mempty
-          f x    = U.singleton x
+  explMembers (Unique ref) = readIORef ref >>= return . \case
+    Nothing -> mempty
+    Just (ety, _) -> U.singleton ety
 
 -- | A Global contains exactly one component.
---   Initialized with 'mempty'
---   The store will return true for every existence check, but only ever gives (-1) as its inhabitant.
---   The entity argument is ignored when setting/getting a global.
+--   The initial value is 'mempty' from the component's 'Monoid' instance.
+--   When operating on a global, any entity arguments are ignored.
+--   For example, we can get a global component with @get 0@ or @get 1@ or even @get undefined@.
 newtype Global c = Global (IORef c)
 type instance Elem (Global c) = c
 instance Monoid c => ExplInit (Global c) where
@@ -96,21 +99,32 @@
   explSet (Global ref) _ c = writeIORef ref c
 
 -- | An empty type class indicating that the store behaves like a regular map, and can therefore safely be cached.
+--   An example of a store that cannot be cached is 'Unique'.
 class Cachable s
 instance Cachable (Map s)
 instance (KnownNat n, Cachable s) => Cachable (Cache n s)
 
 -- | A cache around another store.
+--   Caches store their members in a fixed-size vector, so operations run in O(1).
+--   Caches can provide huge performance boosts, especially for large numbers of components.
+--   The cache size is given as a type-level argument.
+--
 --   Note that iterating over a cache is linear in cache size, so sparsely populated caches might actually decrease performance.
+--   In general, the exact size of the cache does not matter as long as it reasonably approximates the number of components present.
+--
+--   The cache uses entity (-1) to internally represent missing entities, so be wary when manually manipulating entities.
 data Cache (n :: Nat) s =
   Cache Int (UM.IOVector Int) (VM.IOVector (Elem s)) s
+
+cacheMiss = error "Cache miss!"
+
 type instance Elem (Cache n s) = Elem s
 
 instance (ExplInit s, KnownNat n, Cachable s) => ExplInit (Cache n s) where
   explInit = do
     let n = fromIntegral$ natVal (Proxy @n)
     tags <- UM.replicate n (-1)
-    cache <- VM.new n
+    cache <- VM.replicate n cacheMiss
     child <- explInit
     return (Cache n tags cache child)
 
@@ -137,10 +151,13 @@
     VM.unsafeWrite cache index x
 
 instance ExplDestroy s => ExplDestroy (Cache n s) where
-  explDestroy (Cache n tags _ s) ety = do
+  explDestroy (Cache n tags cache s) ety = do
+    let index = ety `rem` n
     tag <- UM.unsafeRead tags (ety `rem` n)
     if tag == ety
-       then UM.unsafeWrite tags (ety `rem` n) (-1)
+       then do
+         UM.unsafeWrite tags  index (-1)
+         VM.unsafeWrite cache index cacheMiss
        else explDestroy s ety
 
 instance ExplMembers s => ExplMembers (Cache n s) where
diff --git a/src/Apecs/System.hs b/src/Apecs/System.hs
--- a/src/Apecs/System.hs
+++ b/src/Apecs/System.hs
@@ -45,7 +45,7 @@
   s :: Storage c <- getStore
   liftIO$ explExists s ety
 
--- | Maps a function over all entities with a @cx@, and writes their @cy@
+-- | Maps a function over all entities with a @cx@, and writes their @cy@.
 {-# INLINE cmap #-}
 cmap :: forall w cx cy. (Get w cx, Members w cx, Set w cy)
      => (cx -> cy) -> System w ()
@@ -58,7 +58,7 @@
       r <- explGet sx e
       explSet sy e (f r)
 
--- | Monadically iterates over all entites with a cx, and writes their cy
+-- | Monadically iterates over all entites with a @cx@, and writes their @cy@.
 {-# INLINE cmapM #-}
 cmapM :: forall w cx cy. (Get w cx, Set w cy, Members w cx)
       => (cx -> System w cy) -> System w ()
@@ -71,7 +71,7 @@
     y <- sys x
     liftIO$ explSet sy e y
 
--- | Monadically iterates over all entites with a cx
+-- | Monadically iterates over all entites with a @cx@
 {-# INLINE cmapM_ #-}
 cmapM_ :: forall w c a. (Get w c, Members w c)
        => (c -> System w a) -> System w ()
@@ -82,8 +82,38 @@
     x <- liftIO$ explGet s ety
     sys x
 
+-- | Fold over the game world; for example, @cfold max (minBound :: Foo)@ will find the maximum value of @Foo@.
+--   Strict in the accumulator.
+{-# INLINE cfold #-}
+cfold :: forall w c a. (Members w c, Get w c)
+      => (a -> c -> a) -> a -> System w a
+cfold f a0 = do
+  s :: Storage c <- getStore
+  sl <- liftIO$ explMembers s
+  liftIO$ U.foldM' (\a e -> f a <$> explGet s e) a0 sl
+
+-- | Monadically fold over the game world.
+--   Strict in the accumulator.
+{-# INLINE cfoldM #-}
+cfoldM :: forall w c a. (Members w c, Get w c)
+       => (a -> c -> System w a) -> a -> System w a
+cfoldM sys a0 = do
+  s :: Storage c <- getStore
+  sl <- liftIO$ explMembers s
+  U.foldM' (\a e -> liftIO (explGet s e) >>= sys a) a0 sl
+
+-- | Monadically fold over the game world.
+--   Strict in the accumulator.
+{-# INLINE cfoldM_ #-}
+cfoldM_ :: forall w c a. (Members w c, Get w c)
+       => (a -> c -> System w a) -> a -> System w ()
+cfoldM_ sys a0 = do
+  s :: Storage c <- getStore
+  sl <- liftIO$ explMembers s
+  U.foldM'_ (\a e -> liftIO (explGet s e) >>= sys a) a0 sl
+
 -- | Get all components @c@.
---   Call as @[(c,Entity)]@ to read the entity/index.
+--   Call as @[(c,Entity)]@ to also read the entity index.
 {-# INLINE getAll #-}
 getAll :: forall w c. (Get w c, Members w c)
       => System w [c]
@@ -91,7 +121,6 @@
   s :: Storage c <- getStore
   sl <- liftIO$ explMembers s
   forM (U.toList sl) $ liftIO . explGet s
-
 
 -- | Destroys component @c@ for the given entity.
 -- Note that @c@ is a phantom argument, used only to convey the type of the entity to be destroyed.
diff --git a/src/Apecs/Util.hs b/src/Apecs/Util.hs
--- a/src/Apecs/Util.hs
+++ b/src/Apecs/Util.hs
@@ -34,9 +34,10 @@
 import           Apecs.System
 import           Apecs.Core
 
--- | Convenience entity (-1), used in places where the exact entity value does not matter, i.e. a global store.
+-- | Convenience entity, for use in places where the entity value does not matter, i.e. a global store.
+-- Its value is -2, to avoid potential conflicts with caches, which reserve -1.
 global :: Entity
-global = Entity (-1)
+global = Entity (-2)
 
 -- | Component used by newEntity to track the number of issued entities.
 --   Automatically added to any world created with @makeWorld@
