diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -11,8 +11,18 @@
 ## Prerequisites
 
 * `cabal` version `2.2` or later
+* Depending on your use case you may need additional package dependencies.  These can be found in the library dependencies of the examples
+  library component in the cabal file.
 
 ## Memory benchmark
+
+If you need a repl to run any of the Haskell examples in this README, please run the command:
+
+```bash
+cabal v2-repl lib:examples
+```
+
+For rexamples these examples are also found in Haskell modules under the `examples` directory.
 
 ### Parsing large Json files in Scala with Argonaut
 
diff --git a/examples/Example1.hs b/examples/Example1.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example1.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE BangPatterns #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-matches     #-}
+{-# OPTIONS_GHC -fno-warn-name-shadowing     #-}
+{-# OPTIONS_GHC -fno-warn-unused-local-binds #-}
+
+module Example1 where
+
+import Data.Aeson
+
+import qualified Data.ByteString.Lazy as LBS
+
+example :: IO ()
+example = do
+  !bs <- LBS.readFile "corpus/bench/hospitalisation.json"
+  let !y = decode bs :: Maybe Value
+  return ()
diff --git a/examples/Example2.hs b/examples/Example2.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example2.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE BangPatterns #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-matches     #-}
+{-# OPTIONS_GHC -fno-warn-name-shadowing     #-}
+{-# OPTIONS_GHC -fno-warn-unused-local-binds #-}
+
+module Example2 where
+
+import qualified HaskellWorks.Data.ByteString                as BS
+import qualified HaskellWorks.Data.Json.Standard.Cursor.Fast as JCF
+
+example :: IO ()
+example = do
+  !jsonBs <- BS.mmap "corpus/bench/hospitalisation.json"
+  let !ibip = JCF.simdToIbBp jsonBs
+  let !c    = JCF.fromBsIbBp jsonBs ibip
+  return ()
diff --git a/examples/Example3.hs b/examples/Example3.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example3.hs
@@ -0,0 +1,24 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-matches     #-}
+{-# OPTIONS_GHC -fno-warn-name-shadowing     #-}
+{-# OPTIONS_GHC -fno-warn-unused-local-binds #-}
+
+module Example3 where
+
+import Control.Monad
+
+import qualified Data.ByteString                             as BS
+import qualified HaskellWorks.Data.Json.Standard.Cursor.Fast as JCF
+import qualified HaskellWorks.Data.TreeCursor                as TC
+
+example :: IO ()
+example = do
+  let fc = TC.firstChild
+  let ns = TC.nextSibling
+  let jsonBs  = "[null, {\"field\": 1}]" :: BS.ByteString
+  let ibip    = JCF.simdToIbBp jsonBs
+  let cursor  = JCF.fromBsIbBp jsonBs ibip
+  let _ = fc cursor
+  let _ = (fc >=> ns) cursor
+  return ()
diff --git a/examples/Example4.hs b/examples/Example4.hs
new file mode 100644
--- /dev/null
+++ b/examples/Example4.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE BangPatterns      #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+{-# OPTIONS_GHC -fno-warn-unused-matches     #-}
+{-# OPTIONS_GHC -fno-warn-name-shadowing     #-}
+{-# OPTIONS_GHC -fno-warn-unused-local-binds #-}
+
+module Example4 where
+
+import Control.Monad
+import Data.Function
+import Data.List
+import HaskellWorks.Data.Json.PartialValue
+import HaskellWorks.Data.Json.Standard.Cursor.Load.Cursor
+import HaskellWorks.Data.Json.Standard.Load.Partial
+import HaskellWorks.Data.MQuery
+import HaskellWorks.Data.MQuery.Micro
+
+import qualified Data.DList as DL
+
+example :: IO ()
+example = do
+  !cursor <- loadPartial "corpus/bench/78mb.json"
+  !cursor <- loadCursorWithIndex "corpus/bench/78mb.json"
+  !cursor <- loadCursor "corpus/bench/78mb.json"
+  !cursor <- loadCursorWithCsPoppyIndex "corpus/bench/78mb.json"
+  let !json = jsonPartialJsonValueAt cursor
+  let q = MQuery (DL.singleton json)
+
+  putPretty $ q >>= item & limit 10
+  putPretty $ q >>= item & page 10 1
+  putPretty $ q >>= item >>= hasKV "founded_year" (JsonPartialNumber 2005) & limit 10
+  putPretty $ q >>= item >>= entry
+  putPretty $ q >>= item >>= entry >>= named "name" & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code")
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code") & onList (uniq . sort)
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount") & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount" >=> castAsInteger ) & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount" >=> castAsInteger ) & aggregate sum
+
+  putPretty $ q >>= item & limit 10
+  putPretty $ q >>= item & page 10 1
+  putPretty $ q >>= item >>= entry
+  putPretty $ q >>= item >>= entry >>= named "name" & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code" >=> asString)
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code" >=> asString) & onList (uniq . sort)
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount") & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount" >=> castAsInteger ) & limit 10
+  putPretty $ q >>= (item >=> entry >=> named "acquisition" >=> having (entry >=> named "price_currency_code" >=> asString >=> valueOf "USD") >=> entry >=> named "price_amount" >=> castAsInteger ) & aggregate sum
+
+  return ()
diff --git a/hw-json.cabal b/hw-json.cabal
--- a/hw-json.cabal
+++ b/hw-json.cabal
@@ -1,7 +1,7 @@
 cabal-version:  2.2
 
 name:                   hw-json
-version:                1.3.2.0
+version:                1.3.2.1
 synopsis:               Memory efficient JSON parser
 description:            Memory efficient JSON parser. Please see README.md
 category:               Data
@@ -50,10 +50,10 @@
 common dlist                      { build-depends: dlist                      >= 0.8        && < 0.9    }
 common doctest                    { build-depends: doctest                    >= 0.16.2     && < 0.17   }
 common doctest-discover           { build-depends: doctest-discover           >= 0.2        && < 0.3    }
-common generic-lens               { build-depends: generic-lens               >= 1.2.0.1    && < 1.3    }
+common generic-lens               { build-depends: generic-lens               >= 1.2.0.1    && < 2.1    }
 common hedgehog                   { build-depends: hedgehog                   >= 0.6        && < 1.1    }
 common hspec                      { build-depends: hspec                      >= 2.4        && < 3      }
-common hw-balancedparens          { build-depends: hw-balancedparens          >= 0.3.0.0    && < 0.4    }
+common hw-balancedparens          { build-depends: hw-balancedparens          >= 0.3.0.0    && < 0.5    }
 common hw-bits                    { build-depends: hw-bits                    >= 0.7.0.5    && < 0.8    }
 common hw-hspec-hedgehog          { build-depends: hw-hspec-hedgehog          >= 0.1.0.4    && < 0.2    }
 common hw-json-simd               { build-depends: hw-json-simd               >= 0.1.0.2    && < 0.2    }
@@ -169,6 +169,7 @@
                       , aeson
                       , attoparsec
                       , bytestring
+                      , dlist
                       , hedgehog
                       , hspec
                       , hw-balancedparens
@@ -177,6 +178,7 @@
                       , hw-json
                       , hw-json-simple-cursor
                       , hw-json-standard-cursor
+                      , hw-mquery
                       , hw-prim
                       , hw-rankselect
                       , hw-rankselect-base
@@ -197,6 +199,21 @@
                         HaskellWorks.Data.Json.TypeSpec
                         HaskellWorks.Data.Json.ValueSpec
 
+library examples
+  import:               base, config
+                      , aeson
+                      , bytestring
+                      , dlist
+                      , hw-json
+                      , hw-json-standard-cursor
+                      , hw-mquery
+                      , hw-prim
+  hs-source-dirs:       examples
+  other-modules:        Example1
+                        Example2
+                        Example3
+                        Example4
+
 benchmark bench
   import:               base, config
                       , bytestring
@@ -209,14 +226,14 @@
   main-is:              Main.hs
   hs-source-dirs:       bench
 
-test-suite hw-json-doctest
+test-suite doctest
   import:               base, config
                       , doctest
                       , doctest-discover
                       , hw-json
   default-language:     Haskell2010
   type:                 exitcode-stdio-1.0
-  ghc-options:          -threaded
+  ghc-options:          -threaded -rtsopts -with-rtsopts=-N
   main-is:              DoctestDriver.hs
   HS-Source-Dirs:       doctest
   build-tool-depends:   doctest-discover:doctest-discover
diff --git a/src/HaskellWorks/Data/Json/PartialValue.hs b/src/HaskellWorks/Data/Json/PartialValue.hs
--- a/src/HaskellWorks/Data/Json/PartialValue.hs
+++ b/src/HaskellWorks/Data/Json/PartialValue.hs
@@ -48,6 +48,19 @@
 import qualified Data.Text                        as T
 import qualified HaskellWorks.Data.BalancedParens as BP
 
+-- | Partial JSON type.
+--
+-- This data type has an additional 'JsonPartialError' data constructor to indicate parsing
+-- errors.  This allows parsing to be more lazy because parsing errors may now be expressed
+-- anywhere in the parsed document so the parser no longer needs to make a verdict about whether
+-- there are any parsing errors in the entire document.
+--
+-- See 'jsonPartialJsonValueAt' on how to parse JSON text into this datatype.
+--
+-- Although this data type allows for lazier parsing it doesn't allow for sub-trees to be
+-- garbage collected if a reference to an ancestor node is held.  To avoid holding onto
+-- sub-trees that are no longer needed without having to drop references to ancestors use
+-- 'HaskellWorks.Data.Json.LightJson.LightJson' instead.
 data JsonPartialValue
   = JsonPartialString Text
   | JsonPartialNumber Double
@@ -59,6 +72,15 @@
   deriving (Eq, Show, Ord)
 
 class JsonPartialValueAt a where
+  -- | Get a JSON partial value from another type
+  --
+  -- This function can always "succeed" because the data type it returns allows for the document value
+  -- to contain an arbitrary number of errors.  This means errors can be reported in document nodes
+  -- as parsing occurs lazily.
+  --
+  -- There are garbage collection implementations you may want to consider.  If you would like to be
+  -- able to hold onto ancestor nodes and still be able to garbage collect visited sub-trees, then
+  -- consider using 'HaskellWorks.Data.Json.LightJson.lightJsonAt' instead.
   jsonPartialJsonValueAt :: a -> JsonPartialValue
 
 data JsonPartialField = JsonPartialField Text JsonPartialValue
diff --git a/src/HaskellWorks/Data/Json/Value.hs b/src/HaskellWorks/Data/Json/Value.hs
--- a/src/HaskellWorks/Data/Json/Value.hs
+++ b/src/HaskellWorks/Data/Json/Value.hs
@@ -15,6 +15,17 @@
 import qualified Data.ByteString                  as BS
 import qualified Data.Text                        as T
 
+-- | Traditional JSON type.
+--
+-- This type has the a constructor per JSON data type as is typical for JSON in most libraries.
+--
+-- See 'jsonValueAt' on how to parse JSON text into this datatype.
+--
+-- Although Haskell data types are lazy by default, you will not get a fully lazy data structure
+-- when parsing to this type because there is no way to express parsing errors in this datatype.
+--
+-- For a data type that gives you lazier behaviour, see other alternatives such as
+-- 'HaskellWorks.Data.Json.PartialValue.JsonPartialValue' or 'HaskellWorks.Data.Json.LightJson.LightJson'.
 data JsonValue
   = JsonString Text
   | JsonNumber Double
@@ -25,6 +36,17 @@
   deriving (Eq, Show)
 
 class JsonValueAt a where
+  -- | Get a JSON value from another type
+  --
+  -- The @hw-json@ library does not do full JSON validation for efficiency reasons, but parsing can
+  -- fail if the JSON is malformed.  When parsing fails, then 'Left' will be returned.
+  --
+  -- If 'Right' is returned then that means there are no parsing failures, which implies "knowing"
+  -- that there parsing failures in the entire document, which implies that pattern matching on
+  -- 'Right' evaluates the entire document.
+  --
+  -- This limits the laziness of the JSON parsing.  For lazier alternatives, see
+  -- 'HaskellWorks.Data.Json.PartialValue.jsonPartialJsonValueAt' or 'HaskellWorks.Data.Json.LightJson.lightJsonAt'.
   jsonValueAt :: a -> Either DecodeError JsonValue
 
 instance JsonValueAt JsonIndex where
