diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # Changelog for can-i-haz
 
+## 0.1.0.1
+
+* Added documentation.
+* Export the SearchSuccessful type which might aid hand-writing instances.
+
 ## 0.1.0.0
 
 Initial release.
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,3 +1,64 @@
 # can-i-haz
 
+[![Build Status][travis-badge]][travis]
+[![Hackage][hackage-badge]][hackage]
+[![Stackage LTS][stackage-lts-badge]][stackage-lts]
+[![Stackage Nightly][stackage-nightly-badge]][stackage-nightly]
+
 `Generic` implementation of the Has-pattern (mostly useful with `MonadReader`).
+
+## Motivation
+
+Assume there are two types representing the `MonadReader` environments
+for different parts of an app:
+```haskell
+data DbConfig = DbConfig { .. }
+data WebConfig = WebConfig { .. }
+```
+as well as a single type containing both of those:
+```haskell
+data AppEnv = AppEnv
+  { dbConfig :: DbConfig
+  , webConfig :: WebConfig
+  }
+```
+
+What should be the `MonadReader` constraint of the DB module and web module respectively?
+1. It could be `MonadReader AppEnv m` for both, introducing unnecessary coupling.
+2. Or it could be `MonadReader DbConfig m` for the DB module
+   and `MonadReader WebConfig m` for the web module respectively,
+   but combining them becomes a pain.
+
+Or, it could be `MonadReader r m, Has DbConfig r` for the DB module,
+where `Has` class allows projecting `DbConfig` out of some `r`,
+and similarly for the web module!
+This approach keeps both modules decoupled, while allowing using them in the same monad stack.
+
+The only downside is that now one has to define the `Has` class
+and write tediuos instances for the `AppEnv` type
+(and potentially other types in case of tests).
+
+## The solution
+
+This library saves you from this unnecessary boilerplate!
+The only thing you have to do is to append the `deriving`-clause:
+```haskell
+data AppEnv = AppEnv
+  { dbConfig :: DbConfig
+  , webConfig :: WebConfig
+  } deriving (Generic, Has DbConfig, Has WebConfig)
+```
+and use `ask extract` instead of `ask` (but this is something you'd have to do anyway).
+
+## Documentation
+
+Perhaps the best source is the [Haddock docs](http://hackage.haskell.org/package/can-i-haz/docs/Control-Monad-Reader-Has.html).
+
+[travis]:        <https://travis-ci.org/0xd34df00d/can-i-haz>
+[travis-badge]:  <https://travis-ci.org/0xd34df00d/can-i-haz.svg?branch=master>
+[hackage]:       <https://hackage.haskell.org/package/can-i-haz>
+[hackage-badge]: <https://img.shields.io/hackage/v/can-i-haz.svg>
+[stackage-lts-badge]: <http://stackage.org/package/can-i-haz/badge/lts>
+[stackage-nightly-badge]: <http://stackage.org/package/can-i-haz/badge/nightly>
+[stackage-lts]: <http://stackage.org/lts/package/can-i-haz>
+[stackage-nightly]: <http://stackage.org/nightly/package/can-i-haz>
diff --git a/can-i-haz.cabal b/can-i-haz.cabal
--- a/can-i-haz.cabal
+++ b/can-i-haz.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 859b8021274842401b027ff7b3ee5ec1352f7970b8feb144c40deffa5a44b026
+-- hash: 1b0fd0317bcbd2ea753912693f9779a96e7743d0610d5c3c77e30e0206b23b70
 
 name:           can-i-haz
-version:        0.1.0.0
+version:        0.1.0.1
 synopsis:       Generic implementation of the Has pattern
 description:    Please see the README on GitHub at <https://github.com/0xd34df00d/can-i-haz#readme>
 category:       Control
diff --git a/src/Control/Monad/Reader/Has.hs b/src/Control/Monad/Reader/Has.hs
--- a/src/Control/Monad/Reader/Has.hs
+++ b/src/Control/Monad/Reader/Has.hs
@@ -1,9 +1,81 @@
 {-# LANGUAGE TypeOperators, DataKinds, PolyKinds, TypeFamilies, ConstraintKinds #-}
 {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, UndecidableInstances, FlexibleContexts #-}
 {-# LANGUAGE ScopedTypeVariables, DefaultSignatures #-}
+{-# LANGUAGE Safe #-}
+{-# OPTIONS_HADDOCK show-extensions #-}
 
+{-|
+Description : Generic implementation of the Has pattern
+Stability   : experimental
+
+This module defines a class 'Has' intended to be used with the 'Control.Monad.Reader.MonadReader' class
+or 'Control.Monad.Reader.Reader' / 'Control.Monad.Reader.ReaderT' types.
+
+= The problem
+
+Assume there are two types representing the 'Control.Monad.Reader.MonadReader' environments
+for different parts of an app:
+
+@
+data DbConfig = DbConfig { .. }
+data WebConfig = WebConfig { .. }
+@
+
+as well as a single type containing both of those:
+
+@
+data AppEnv = AppEnv
+  { dbConfig :: DbConfig
+  , webConfig :: WebConfig
+  }
+@
+
+What should be the @MonadReader@ constraint of the DB module and web module respectively?
+
+1. It could be @MonadReader AppEnv m@ for both, introducing unnecessary coupling.
+
+2. Or it could be @MonadReader DbConfig m@ for the DB module and
+   @MonadReader WebConfig m@ for the web module respectively, but combining them becomes a pain.
+
+Or, it could be @MonadReader r m, Has DbConfig r@ for the DB module (and similarly for the web module),
+where some appropriately defined @Has part record@ class allows projecting @part@ out of some @record@.
+This approach keeps both modules decoupled, while allowing using them in the same monad stack.
+
+The only downside is that now one has to define the @Has@ class and write tediuos instances for the @AppEnv@ type
+(and potentially other types in case of tests).
+
+But why bother doing the work that the machine will happily do for you?
+
+= The solution
+
+This module defines the generic 'Has' class as well as hides all the boilerplate behind "GHC.Generics",
+so all you have to do is to add the corresponding @deriving@-clause:
+
+@
+data AppEnv = AppEnv
+  { dbConfig :: DbConfig
+  , webConfig :: WebConfig
+  } deriving (Generic, Has DbConfig, Has WebConfig)
+@
+
+and use @ask extract@ instead of @ask@ (but this is something you'd have to do anyway).
+
+= Type safety
+
+What should happen if @record@ does not have any field of type @part@ at all?
+Of course, this means that we cannot project @part@ out of @record@, and no 'Has' instance can be derived at all.
+Indeed, this library will fail to generate an instance in this case.
+
+On the other hand, what should happen if @record@ contains multiple values of type @part@,
+perhaps on different levels of nesting? While technically we could make an arbitrary choice, like taking
+the first one in breadth-first or depth-first order, we instead decide that such a choice is inherently ambiguous,
+so this library will fail to generate an instance in this case as well.
+
+-}
+
 module Control.Monad.Reader.Has
 ( Has(..)
+, SuccessfulSearch
 ) where
 
 import Data.Proxy
@@ -40,13 +112,25 @@
 instance GHas path part r => GHas ('R path) part (l :*: r) where
   gextract _ (_ :*: r) = gextract (Proxy :: Proxy path) r
 
+-- | Type alias representing that the search of @part@ in @record@ has been successful.
+--
+-- The @path@ is used to guide the default generic implementation of 'Has'.
 type SuccessfulSearch part record path = (Search part (Rep record) ~ 'Found path, GHas path part (Rep record))
 
+-- | The @Has part record@ class is used for records of type @record@ supporting
+-- projecting out a value of type @part@.
 class Has part record where
+  -- | Extract a subvalue of type @part@ from the @record@.
+  --
+  -- The default implementation searches for some value of the type @part@ in @record@ (potentially recursively)
+  -- and returns that value. The default implementation typechecks if and only if
+  -- there is a single subvalue of type @part@ in @record@.
   extract :: record -> part
+
   default extract :: forall path. (Generic record, SuccessfulSearch part record path) => record -> part
   extract = gextract (Proxy :: Proxy path) . from
 
+-- | Each type allows projecting itself (and that is an 'id' projection).
 instance Has record record where
   extract = id
 
