diff --git a/hw-json.cabal b/hw-json.cabal
--- a/hw-json.cabal
+++ b/hw-json.cabal
@@ -1,5 +1,5 @@
 name:                   hw-json
-version:                0.0.0.3
+version:                0.0.0.4
 synopsis:               Conduits for tokenizing streams.
 description:            Please see README.md
 homepage:               http://github.com/haskell-works/hw-json#readme
@@ -12,7 +12,6 @@
 build-type:             Simple
 extra-source-files:     README.md
 cabal-version:          >= 1.10
-data-files:             test/data/sample.json
 
 executable hw-json-example
   hs-source-dirs:       app
@@ -44,7 +43,6 @@
                       , HaskellWorks.Data.Json.Succinct.Cursor
                       , HaskellWorks.Data.Json.Succinct.Cursor.BalancedParens
                       , HaskellWorks.Data.Json.Succinct.Cursor.BlankedJson
-                      , HaskellWorks.Data.Json.Succinct.Cursor.CursorType
                       , HaskellWorks.Data.Json.Succinct.Cursor.FromJsonCursor
                       , HaskellWorks.Data.Json.Succinct.Cursor.InterestBits
                       , HaskellWorks.Data.Json.Succinct.Cursor.Internal
@@ -54,6 +52,8 @@
                       , HaskellWorks.Data.Json.Token
                       , HaskellWorks.Data.Json.Type
                       , HaskellWorks.Data.Json.Value
+                      , HaskellWorks.Data.Json.Value.ByteString
+                      , HaskellWorks.Data.Json.Value.Internal
   build-depends:        base                            >= 4.7  && < 5
                       , array
                       , attoparsec
diff --git a/src/HaskellWorks/Data/Json/Succinct/Cursor.hs b/src/HaskellWorks/Data/Json/Succinct/Cursor.hs
--- a/src/HaskellWorks/Data/Json/Succinct/Cursor.hs
+++ b/src/HaskellWorks/Data/Json/Succinct/Cursor.hs
@@ -3,6 +3,5 @@
   ( module X
   ) where
 
-import           HaskellWorks.Data.Json.Succinct.Cursor.CursorType          as X
 import           HaskellWorks.Data.Json.Succinct.Cursor.Internal            as X
 import           HaskellWorks.Data.Json.Succinct.Cursor.Token               as X
diff --git a/src/HaskellWorks/Data/Json/Succinct/Cursor/CursorType.hs b/src/HaskellWorks/Data/Json/Succinct/Cursor/CursorType.hs
deleted file mode 100644
--- a/src/HaskellWorks/Data/Json/Succinct/Cursor/CursorType.hs
+++ /dev/null
@@ -1,66 +0,0 @@
-{-# LANGUAGE FlexibleContexts      #-}
-{-# LANGUAGE FlexibleInstances     #-}
-{-# LANGUAGE InstanceSigs          #-}
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module HaskellWorks.Data.Json.Succinct.Cursor.CursorType
-  ( HasJsonCursorType(..)
-  , JsonCursorType(..)
-  , jsonCursorPos
-  ) where
-
-import qualified Data.ByteString                                            as BS
-import           Data.Char
-import           HaskellWorks.Data.Json.Succinct.Cursor.Internal
-import           HaskellWorks.Data.Positioning
-import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Rank1
-import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Select1
-import           HaskellWorks.Data.Vector.VectorLike
-
-data JsonCursorType
-  = JsonCursorArray
-  | JsonCursorBool
-  | JsonCursorNull
-  | JsonCursorNumber
-  | JsonCursorObject
-  | JsonCursorString
-  deriving (Eq, Show)
-
-class HasJsonCursorType k where
-  jsonCursorType :: k -> Maybe JsonCursorType
-
-jsonCursorType' :: Char -> Maybe JsonCursorType
-jsonCursorType' c = case c of
-  '[' -> Just JsonCursorArray
-  't' -> Just JsonCursorBool
-  'f' -> Just JsonCursorBool
-  '0' -> Just JsonCursorNumber
-  '1' -> Just JsonCursorNumber
-  '2' -> Just JsonCursorNumber
-  '3' -> Just JsonCursorNumber
-  '4' -> Just JsonCursorNumber
-  '5' -> Just JsonCursorNumber
-  '6' -> Just JsonCursorNumber
-  '7' -> Just JsonCursorNumber
-  '8' -> Just JsonCursorNumber
-  '9' -> Just JsonCursorNumber
-  '+' -> Just JsonCursorNumber
-  '-' -> Just JsonCursorNumber
-  'n' -> Just JsonCursorNull
-  '{' -> Just JsonCursorObject
-  '"' -> Just JsonCursorString
-  _   -> Nothing
-
-jsonCursorPos :: (Rank1 w, Select1 v, VectorLike s) => JsonCursor s v w -> Position
-jsonCursorPos k = toPosition (select1 ik (rank1 bpk (cursorRank k)) - 1)
-  where ik  = interests k
-        bpk = balancedParens k
-
-jsonCursorElemAt :: (Rank1 w, Select1 v, VectorLike s) => JsonCursor s v w -> Elem s
-jsonCursorElemAt k = cursorText k !!! jsonCursorPos k
-
-instance (Rank1 i, Select1 i, Rank1 b) => HasJsonCursorType (JsonCursor String i b) where
-  jsonCursorType = jsonCursorType' . jsonCursorElemAt
-
-instance (Rank1 i, Select1 i, Rank1 b) => HasJsonCursorType (JsonCursor BS.ByteString i b) where
-  jsonCursorType = jsonCursorType' . chr . fromIntegral . jsonCursorElemAt
diff --git a/src/HaskellWorks/Data/Json/Succinct/Cursor/FromJsonCursor.hs b/src/HaskellWorks/Data/Json/Succinct/Cursor/FromJsonCursor.hs
--- a/src/HaskellWorks/Data/Json/Succinct/Cursor/FromJsonCursor.hs
+++ b/src/HaskellWorks/Data/Json/Succinct/Cursor/FromJsonCursor.hs
@@ -17,7 +17,7 @@
 class FromJsonCursor t v w a where
   fromJsonCursor :: JsonCursor t v w -> a
 
-instance (TreeCursor (JsonCursor BS.ByteString v w), Rank1 w, Select1 v, TestBit w) => FromJsonCursor BS.ByteString v w (JsonValue BS.ByteString BS.ByteString) where
+instance (TreeCursor (JsonCursor BS.ByteString v w), Rank1 w, Select1 v, TestBit w) => FromJsonCursor BS.ByteString v w (GenJsonValue BS.ByteString BS.ByteString) where
   fromJsonCursor k = case jsonTokenAt k of
     Just JsonTokenBraceL          -> undefined
     Just JsonTokenBraceR          -> undefined
diff --git a/src/HaskellWorks/Data/Json/Succinct/Cursor/Internal.hs b/src/HaskellWorks/Data/Json/Succinct/Cursor/Internal.hs
--- a/src/HaskellWorks/Data/Json/Succinct/Cursor/Internal.hs
+++ b/src/HaskellWorks/Data/Json/Succinct/Cursor/Internal.hs
@@ -6,11 +6,13 @@
 
 module HaskellWorks.Data.Json.Succinct.Cursor.Internal
   ( JsonCursor(..)
+  , jsonCursorPos
   ) where
 
 import qualified Data.ByteString                                          as BS
 import qualified Data.ByteString.Char8                                    as BSC
 import           Data.ByteString.Internal                                 as BSI
+import           Data.Char
 import qualified Data.List                                                as L
 import qualified Data.Map                                                 as M
 import           Data.String
@@ -27,7 +29,7 @@
 import           HaskellWorks.Data.Json.Succinct.Cursor.BlankedJson
 import           HaskellWorks.Data.Json.Succinct.Cursor.InterestBits
 import           HaskellWorks.Data.Json.Type
-import           HaskellWorks.Data.Json.Value
+import           HaskellWorks.Data.Json.Value.Internal
 import           HaskellWorks.Data.Positioning
 import qualified HaskellWorks.Data.Succinct.BalancedParens                as BP
 import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Rank0
@@ -107,40 +109,59 @@
   parent :: JsonCursor t v u -> Maybe (JsonCursor t v u)
   parent k = let mq = BP.parent (balancedParens k) (cursorRank k) in (\q -> k { cursorRank = q }) <$> mq
 
-  depth :: JsonCursor t v u -> Count
+  depth :: JsonCursor t v u -> Maybe Count
   depth k = BP.depth (balancedParens k) (cursorRank k)
 
-  subtreeSize :: JsonCursor t v u -> Count
+  subtreeSize :: JsonCursor t v u -> Maybe Count
   subtreeSize k = BP.subtreeSize (balancedParens k) (cursorRank k)
 
 wIsJsonNumberDigit :: Word8 -> Bool
 wIsJsonNumberDigit w = (w >= _0 && w <= _9) || w == _hyphen
 
+jsonCursorPos :: (Rank1 w, Select1 v, VectorLike s) => JsonCursor s v w -> Position
+jsonCursorPos k = toPosition (select1 ik (rank1 bpk (cursorRank k)) - 1)
+  where ik  = interests k
+        bpk = balancedParens k
+
+instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => JsonTypeAt (JsonCursor String v w) where
+  jsonTypeAtPosition p k = case vDrop (toCount p) (cursorText k) of
+    c:_ | fromIntegral (ord c) == _bracketleft      -> Just JsonTypeArray
+    c:_ | fromIntegral (ord c) == _f                -> Just JsonTypeBool
+    c:_ | fromIntegral (ord c) == _t                -> Just JsonTypeBool
+    c:_ | fromIntegral (ord c) == _n                -> Just JsonTypeNull
+    c:_ | wIsJsonNumberDigit (fromIntegral (ord c)) -> Just JsonTypeNumber
+    c:_ | fromIntegral (ord c) == _braceleft        -> Just JsonTypeObject
+    c:_ | fromIntegral (ord c) == _quotedbl         -> Just JsonTypeString
+    _                                               -> Nothing
+
+  jsonTypeAt k = jsonTypeAtPosition p k
+    where p   = lastPositionOf (select1 ik (rank1 bpk (cursorRank k)))
+          ik  = interests k
+          bpk = balancedParens k
+
 instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => JsonTypeAt (JsonCursor BS.ByteString v w) where
-  jsonTypeAtPosition p k = if bpk .?. p
-    then case BS.uncons (vDrop (toCount p) (cursorText k)) of
-      Just (c, _) | c == _bracketleft     -> Just JsonTypeArray
-      Just (c, _) | c == _t               -> Just JsonTypeBool
-      Just (c, _) | c == _n               -> Just JsonTypeNull
-      Just (c, _) | wIsJsonNumberDigit c  -> Just JsonTypeNumber
-      Just (c, _) | c == _braceleft       -> Just JsonTypeObject
-      Just (c, _) | c == _quotedbl        -> Just JsonTypeString
-      _                         -> Nothing
-    else Nothing
-    where bpk = balancedParens k
+  jsonTypeAtPosition p k = case BS.uncons (vDrop (toCount p) (cursorText k)) of
+    Just (c, _) | c == _bracketleft     -> Just JsonTypeArray
+    Just (c, _) | c == _f               -> Just JsonTypeBool
+    Just (c, _) | c == _t               -> Just JsonTypeBool
+    Just (c, _) | c == _n               -> Just JsonTypeNull
+    Just (c, _) | wIsJsonNumberDigit c  -> Just JsonTypeNumber
+    Just (c, _) | c == _braceleft       -> Just JsonTypeObject
+    Just (c, _) | c == _quotedbl        -> Just JsonTypeString
+    _                                   -> Nothing
 
   jsonTypeAt k = jsonTypeAtPosition p k
-    where p = toPosition (select1 ik (rank1 bpk (cursorRank k)) - 1)
+    where p   = lastPositionOf (select1 ik (rank1 bpk (cursorRank k)))
           ik  = interests k
           bpk = balancedParens k
 
-instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => JsonValueAt BS.ByteString BS.ByteString (JsonCursor BS.ByteString v w) where
-  jsonValueAt :: JsonCursor BS.ByteString v w -> Maybe (JsonValue BS.ByteString BS.ByteString)
+instance (BP.BalancedParens w, Rank0 w, Rank1 w, Select1 v, TestBit w) => GenJsonValueAt BS.ByteString BS.ByteString (JsonCursor BS.ByteString v w) where
+  jsonValueAt :: JsonCursor BS.ByteString v w -> Maybe (GenJsonValue BS.ByteString BS.ByteString)
   jsonValueAt k = case extractJsonSnippet remainder of
     Just (JsonTypeArray ,  _) -> Just $ JsonArray (arrayValuesAt k)
     Just (JsonTypeBool  , bs) -> case BS.uncons bs of
       Just (c, _) | c == _t   -> Just $ JsonBool True
-      Just (c, _) | c == _t   -> Just $ JsonBool False
+      Just (c, _) | c == _f   -> Just $ JsonBool False
       _                       -> Nothing
     Just (JsonTypeNull  ,  _) -> Just JsonNull
     Just (JsonTypeNumber, bs) -> Just $ JsonNumber bs
@@ -151,15 +172,15 @@
           ik  = interests k
           bpk = balancedParens k
           remainder = (vDrop (toCount p) (cursorText k))
-          genArrayValue :: JsonCursor BS.ByteString v w -> Maybe (JsonValue ByteString ByteString, JsonCursor ByteString v w)
+          genArrayValue :: JsonCursor BS.ByteString v w -> Maybe (GenJsonValue ByteString ByteString, JsonCursor ByteString v w)
           genArrayValue j = (,) <$> jsonValueAt j <*> nextSibling j
-          arrayValuesAt :: JsonCursor BS.ByteString v w -> [JsonValue BS.ByteString BS.ByteString]
+          arrayValuesAt :: JsonCursor BS.ByteString v w -> [GenJsonValue BS.ByteString BS.ByteString]
           arrayValuesAt j = case firstChild j of
             Just c  -> L.unfoldr genArrayValue c
             Nothing -> []
-          mapValuesAt :: JsonCursor BS.ByteString v w -> M.Map ByteString (JsonValue ByteString ByteString)
+          mapValuesAt :: JsonCursor BS.ByteString v w -> M.Map ByteString (GenJsonValue ByteString ByteString)
           mapValuesAt j = M.fromList (pairwise (arrayValuesAt j) >>= asField)
-          asField :: (JsonValue ByteString ByteString, JsonValue ByteString ByteString) -> [(ByteString, JsonValue ByteString ByteString)]
+          asField :: (GenJsonValue ByteString ByteString, GenJsonValue ByteString ByteString) -> [(ByteString, GenJsonValue ByteString ByteString)]
           asField (a, b) = case a of
             JsonString s  -> [(s, b)]
             _             -> []
diff --git a/src/HaskellWorks/Data/Json/Succinct/Cursor/Token.hs b/src/HaskellWorks/Data/Json/Succinct/Cursor/Token.hs
--- a/src/HaskellWorks/Data/Json/Succinct/Cursor/Token.hs
+++ b/src/HaskellWorks/Data/Json/Succinct/Cursor/Token.hs
@@ -6,7 +6,6 @@
 import qualified Data.Attoparsec.ByteString.Char8                           as ABC
 import           Data.ByteString.Internal                                   as BSI
 import           HaskellWorks.Data.Bits.BitWise
-import           HaskellWorks.Data.Json.Succinct.Cursor.CursorType
 import           HaskellWorks.Data.Json.Succinct.Cursor.Internal
 import           HaskellWorks.Data.Json.Token.Tokenize
 import           HaskellWorks.Data.Positioning
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
@@ -1,17 +1,5 @@
-{-# LANGUAGE MultiParamTypeClasses #-}
-
-module HaskellWorks.Data.Json.Value where
-
-import Data.Map
-
-data JsonValue s n
-  = JsonString s
-  | JsonNumber n
-  | JsonObject (Map s (JsonValue s n))
-  | JsonArray [JsonValue s n]
-  | JsonBool Bool
-  | JsonNull
-  deriving (Eq, Show)
+module HaskellWorks.Data.Json.Value
+  ( module X
+  ) where
 
-class JsonValueAt s n a where
-  jsonValueAt :: a -> Maybe (JsonValue s n)
+import HaskellWorks.Data.Json.Value.Internal as X
diff --git a/src/HaskellWorks/Data/Json/Value/ByteString.hs b/src/HaskellWorks/Data/Json/Value/ByteString.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Json/Value/ByteString.hs
@@ -0,0 +1,8 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module HaskellWorks.Data.Json.Value.ByteString where
+
+import Data.ByteString
+import HaskellWorks.Data.Json.Value.Internal
+
+type JsonValue = GenJsonValue ByteString ByteString
diff --git a/src/HaskellWorks/Data/Json/Value/Internal.hs b/src/HaskellWorks/Data/Json/Value/Internal.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Json/Value/Internal.hs
@@ -0,0 +1,17 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module HaskellWorks.Data.Json.Value.Internal where
+
+import Data.Map
+
+data GenJsonValue s n
+  = JsonString s
+  | JsonNumber n
+  | JsonObject (Map s (GenJsonValue s n))
+  | JsonArray [GenJsonValue s n]
+  | JsonBool Bool
+  | JsonNull
+  deriving (Eq, Show)
+
+class GenJsonValueAt s n a where
+  jsonValueAt :: a -> Maybe (GenJsonValue s n)
diff --git a/test/HaskellWorks/Data/Json/Succinct/CursorSpec.hs b/test/HaskellWorks/Data/Json/Succinct/CursorSpec.hs
--- a/test/HaskellWorks/Data/Json/Succinct/CursorSpec.hs
+++ b/test/HaskellWorks/Data/Json/Succinct/CursorSpec.hs
@@ -23,6 +23,7 @@
 import           HaskellWorks.Data.FromForeignRegion
 import           HaskellWorks.Data.Json.Succinct.Cursor                     as C
 import           HaskellWorks.Data.Json.Token
+import           HaskellWorks.Data.Json.Type
 import           HaskellWorks.Data.Json.Value
 import           HaskellWorks.Data.Succinct.BalancedParens.Internal
 import           HaskellWorks.Data.Succinct.BalancedParens.Simple
@@ -31,13 +32,14 @@
 import           HaskellWorks.Data.Succinct.RankSelect.Binary.Basic.Select1
 import           HaskellWorks.Data.Succinct.RankSelect.Binary.Poppy512
 import qualified HaskellWorks.Data.TreeCursor as TC
-import           System.IO.MMap
 import           Test.Hspec
 
 {-# ANN module ("HLint: ignore Redundant do"        :: String) #-}
 {-# ANN module ("HLint: ignore Reduce duplication"  :: String) #-}
 {-# ANN module ("HLint: redundant bracket"          :: String) #-}
 
+type JsonValue = GenJsonValue BS.ByteString BS.ByteString
+
 fc = TC.firstChild
 ns = TC.nextSibling
 pn = TC.parent
@@ -49,55 +51,55 @@
   describe "Cursor for [Bool]" $ do
     it "initialises to beginning of empty object" $ do
       let cursor = "{}" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorObject
+      jsonTypeAt cursor `shouldBe` Just JsonTypeObject
     it "initialises to beginning of empty object preceded by spaces" $ do
       let cursor = " {}" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorObject
+      jsonTypeAt cursor `shouldBe` Just JsonTypeObject
     it "initialises to beginning of number" $ do
       let cursor = "1234" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorNumber
+      jsonTypeAt cursor `shouldBe` Just JsonTypeNumber
     it "initialises to beginning of string" $ do
       let cursor = "\"Hello\"" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorString
+      jsonTypeAt cursor `shouldBe` Just JsonTypeString
     it "initialises to beginning of array" $ do
       let cursor = "[]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorArray
+      jsonTypeAt cursor `shouldBe` Just JsonTypeArray
     it "initialises to beginning of boolean true" $ do
       let cursor = "true" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorBool
+      jsonTypeAt cursor `shouldBe` Just JsonTypeBool
     it "initialises to beginning of boolean false" $ do
       let cursor = "false" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorBool
+      jsonTypeAt cursor `shouldBe` Just JsonTypeBool
     it "initialises to beginning of null" $ do
       let cursor = "null" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      jsonCursorType cursor `shouldBe` Just JsonCursorNull
+      jsonTypeAt cursor `shouldBe` Just JsonTypeNull
     it "cursor can navigate to first child of array" $ do
       let cursor = "[null]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      (fc >=> jsonCursorType) cursor `shouldBe` Just JsonCursorNull
+      (fc >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeNull
     it "cursor can navigate to second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      (fc >=> ns >=> jsonCursorType) cursor `shouldBe` Just JsonCursorObject
+      (fc >=> ns >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeObject
     it "cursor can navigate to first child of object at second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      (fc >=> ns >=> fc >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
+      (fc >=> ns >=> fc >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
     it "cursor can navigate to first child of object at second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      (fc >=> ns >=> fc >=> ns >=> jsonCursorType) cursor `shouldBe` Just JsonCursorNumber
+      (fc >=> ns >=> fc >=> ns >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeNumber
     it "depth at top" $ do
       let cursor = "[null]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      cd cursor `shouldBe` 1
+      cd cursor `shouldBe` Just 1
     it "depth at first child of array" $ do
       let cursor = "[null]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      cd <$> fc cursor `shouldBe` Just 2
+      (fc >=> cd) cursor `shouldBe` Just 2
     it "depth at second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      cd <$> (fc >=> ns) cursor `shouldBe` Just 2
+      (fc >=> ns >=> cd) cursor `shouldBe` Just 2
     it "depth at first child of object at second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      cd <$> (fc >=> ns >=> fc) cursor `shouldBe` Just 3
+      (fc >=> ns >=> fc >=> cd) cursor `shouldBe` Just 3
     it "depth at first child of object at second child of array" $ do
       let cursor = "[null, {\"field\": 1}]" :: JsonCursor String (BitShown [Bool]) (SimpleBalancedParens [Bool])
-      cd <$> (fc >=> ns >=> fc >=> ns) cursor `shouldBe` Just 3
+      (fc >=> ns >=> fc >=> ns >=> cd) cursor `shouldBe` Just 3
   genSpec "DVS.Vector Word8"  (undefined :: JsonCursor BS.ByteString (BitShown (DVS.Vector Word8)) (SimpleBalancedParens (DVS.Vector Word8)))
   genSpec "DVS.Vector Word16" (undefined :: JsonCursor BS.ByteString (BitShown (DVS.Vector Word16)) (SimpleBalancedParens (DVS.Vector Word16)))
   genSpec "DVS.Vector Word32" (undefined :: JsonCursor BS.ByteString (BitShown (DVS.Vector Word32)) (SimpleBalancedParens (DVS.Vector Word32)))
@@ -134,124 +136,132 @@
   , TestBit           u
   , FromForeignRegion (JsonCursor BS.ByteString t u)
   , IsString          (JsonCursor BS.ByteString t u)
-  , HasJsonCursorType (JsonCursor BS.ByteString t u)
-  , JsonValueAt BS.ByteString BS.ByteString (JsonCursor BS.ByteString t u))
+  , GenJsonValueAt BS.ByteString BS.ByteString (JsonCursor BS.ByteString t u))
   => String -> (JsonCursor BS.ByteString t u) -> SpecWith ()
 genSpec t _ = do
-  describe ("Cursor for (" ++ t ++ ")") $ do
-    it "initialises to beginning of empty object" $ do
-      let cursor = "{}" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorObject
-    it "initialises to beginning of empty object preceded by spaces" $ do
-      let cursor = " {}" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorObject
-      jsonValueAt cursor `shouldBe` Just (JsonObject M.empty :: JsonValue BS.ByteString BS.ByteString)
-    it "initialises to beginning of number" $ do
-      let cursor = "1234" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorNumber
-    it "initialises to beginning of string" $ do
-      let cursor = "\"Hello\"" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorString
-    it "initialises to beginning of array" $ do
-      let cursor = "[]" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorArray
-      jsonValueAt cursor `shouldBe` Just (JsonArray [] :: JsonValue BS.ByteString BS.ByteString)
-    it "initialises to beginning of boolean true" $ do
-      let cursor = "true" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorBool
-    it "initialises to beginning of boolean false" $ do
-      let cursor = "false" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorBool
-    it "initialises to beginning of null" $ do
-      let cursor = "null" :: JsonCursor BS.ByteString t u
-      jsonCursorType cursor `shouldBe` Just JsonCursorNull
-    it "cursor can navigate to first child of array" $ do
-      let cursor = "[null]" :: JsonCursor BS.ByteString t u
-      (fc >=> jsonCursorType) cursor `shouldBe` Just JsonCursorNull
-    it "cursor can navigate to second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      (fc >=> ns >=> jsonCursorType) cursor `shouldBe` Just JsonCursorObject
-    it "cursor can navigate to first child of object at second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      (fc >=> ns >=> fc >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-    it "cursor can navigate to first child of object at second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      (fc >=> ns >=> fc >=> ns >=> jsonCursorType) cursor `shouldBe` Just JsonCursorNumber
-    it "depth at top" $ do
-      let cursor = "[null]" :: JsonCursor BS.ByteString t u
-      cd cursor `shouldBe` 1
-    it "depth at first child of array" $ do
-      let cursor = "[null]" :: JsonCursor BS.ByteString t u
-      cd <$> (fc) cursor `shouldBe` Just 2
-    it "depth at second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      cd <$> (fc >=> ns) cursor `shouldBe` Just 2
-    it "depth at first child of object at second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      cd <$> (fc >=> ns >=> fc) cursor `shouldBe` Just 3
-    it "depth at first child of object at second child of array" $ do
-      let cursor = "[null, {\"field\": 1}]" :: JsonCursor BS.ByteString t u
-      cd <$> (fc >=> ns >=> fc >=> ns) cursor `shouldBe` Just 3
-    it "can navigate down and forwards" $ do
-      (fptr, offset, size) <- mmapFileForeignPtr "test/data/sample.json" ReadOnly Nothing
-      let cursor = fromForeignRegion (fptr, offset, size) :: JsonCursor BS.ByteString t u
-      (jsonCursorType                                                                                    ) cursor `shouldBe` Just JsonCursorObject
-      (fc                                                                              >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns                                                                       >=> jsonCursorType) cursor `shouldBe` Just JsonCursorObject
-      (fc >=> ns >=> fc                                                                >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns                                                         >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns                                                  >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns                                           >=> jsonCursorType) cursor `shouldBe` Just JsonCursorObject
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                                    >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns                             >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns                      >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns               >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns        >=> jsonCursorType) cursor `shouldBe` Just JsonCursorString
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> ns >=> jsonCursorType) cursor `shouldBe` Just JsonCursorNumber
-    it "can navigate up" $ do
-      (fptr, offset, size) <- mmapFileForeignPtr "test/data/sample.json" ReadOnly Nothing
-      let cursor = fromForeignRegion (fptr, offset, size) :: JsonCursor BS.ByteString t u
-      (fc >=> pn                                                                             ) cursor `shouldBe`                                    Just cursor
-      (fc >=> ns >=> pn                                                                      ) cursor `shouldBe`                                    Just cursor
-      (fc >=> ns >=> fc >=> pn                                                               ) cursor `shouldBe` (fc >=> ns                            ) cursor
-      (fc >=> ns >=> fc >=> ns >=> pn                                                        ) cursor `shouldBe` (fc >=> ns                            ) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> pn                                                 ) cursor `shouldBe` (fc >=> ns                            ) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> pn                                          ) cursor `shouldBe` (fc >=> ns                            ) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> pn                                   ) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> pn                            ) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> pn                     ) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> pn              ) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> pn       ) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> ns >=> pn) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
-    it "can get subtree size" $ do
-      (fptr, offset, size) <- mmapFileForeignPtr "test/data/sample.json" ReadOnly Nothing
-      let cursor = fromForeignRegion (fptr, offset, size) :: JsonCursor BS.ByteString t u
-      ss                                                                                        cursor  `shouldBe` 45
-      ss <$> (fc                                                                              ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns                                                                       ) cursor `shouldBe` Just 43
-      ss <$> (fc >=> ns >=> fc                                                                ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns                                                         ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns                                                  ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns                                           ) cursor `shouldBe` Just 9
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                                    ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns                             ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns                      ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns               ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns        ) cursor `shouldBe` Just 1
-      ss <$> (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> ns ) cursor `shouldBe` Just 1
-    it "can get token at cursor" $ do
-      (fptr, offset, size) <- mmapFileForeignPtr "test/data/sample.json" ReadOnly Nothing
-      let cursor = fromForeignRegion (fptr, offset, size) :: JsonCursor BS.ByteString t u
-      (jsonTokenAt                                                                                    ) cursor `shouldBe` Just (JsonTokenBraceL                             )
-      (fc                                                                              >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "widget"                    )
-      (fc >=> ns                                                                       >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenBraceL                             )
-      (fc >=> ns >=> fc                                                                >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "debug"                     )
-      (fc >=> ns >=> fc >=> ns                                                         >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "on"                        )
-      (fc >=> ns >=> fc >=> ns >=> ns                                                  >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "window"                    )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns                                           >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenBraceL                             )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                                    >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "title"                     )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns                             >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "Sample Konfabulator Widget")
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns                      >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "name"                      )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns               >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "main_window"               )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns        >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString "width"                     )
-      (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> ns >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenNumber 500.0                       )
+  describe ("Json cursor of type " ++ t) $ do
+    let forJson (cursor :: JsonCursor BS.ByteString t u) f = describe ("of value " ++ show cursor) (f cursor)
+    forJson "{}" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeObject
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonObject M.empty :: JsonValue)
+    forJson " {}" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeObject
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonObject M.empty :: JsonValue)
+    forJson "1234" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeNumber
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonNumber "1234" :: JsonValue)
+    forJson "\"Hello\"" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeString
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonString "\"Hello\"" :: JsonValue)
+    forJson "[]" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeArray
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonArray [] :: JsonValue)
+    forJson "true" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeBool
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonBool True :: JsonValue)
+    forJson "false" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeBool
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonBool False :: JsonValue)
+    forJson "null" $ \cursor -> do
+      it "should have correct type"       $ jsonTypeAt cursor `shouldBe` Just JsonTypeNull
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonNull :: JsonValue)
+    forJson "[null]" $ \cursor -> do
+      it "should have correct type"       $ (fc >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeNull
+      it "should have correct value"      $ jsonValueAt cursor `shouldBe` Just (JsonArray [JsonNull] :: JsonValue)
+      it "should have correct value"      $ ((fc >=> jsonValueAt) cursor) `shouldBe` Just (JsonNull :: JsonValue)
+      it "depth at top"                   $ cd cursor `shouldBe` Just 1
+      it "depth at first child of array"  $ (fc >=> cd) cursor `shouldBe` Just 2
+    forJson "[null, {\"field\": 1}]" $ \cursor -> do
+      it "cursor can navigate to second child of array" $ do
+        (fc >=> ns >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeObject
+        ((fc >=> ns >=> jsonValueAt) cursor) `shouldBe` Just (JsonObject (M.fromList [("\"field\"", JsonNumber "1")]) :: JsonValue)
+        jsonValueAt cursor `shouldBe` Just (JsonArray [JsonNull, JsonObject (M.fromList [("\"field\"", JsonNumber "1")])] :: JsonValue)
+      it "cursor can navigate to first child of object at second child of array" $ do
+        (fc >=> ns >=> fc >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+      it "cursor can navigate to first child of object at second child of array" $ do
+        (fc >=> ns >=> fc >=> ns >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeNumber
+      it "depth at second child of array" $ do
+        (fc >=> ns >=> cd) cursor `shouldBe` Just 2
+      it "depth at first child of object at second child of array" $ do
+        (fc >=> ns >=> fc >=> cd) cursor `shouldBe` Just 3
+      it "depth at first child of object at second child of array" $ do
+        (fc >=> ns >=> fc >=> ns >=> cd) cursor `shouldBe` Just 3
+    describe "For sample Json" $ do
+      let cursor =  "{ \
+                    \    \"widget\": { \
+                    \        \"debug\": \"on\", \
+                    \        \"window\": { \
+                    \            \"name\": \"main_window\", \
+                    \            \"dimensions\": [500, 600.01e-02, true, false, null] \
+                    \        } \
+                    \    } \
+                    \}" :: JsonCursor BS.ByteString t u
+      it "can navigate down and forwards" $ do
+        let array   = JsonArray [JsonNumber "500", JsonNumber "600.01e-02", JsonBool True, JsonBool False, JsonNull] :: JsonValue
+        let object1 = JsonObject (M.fromList [("\"name\"", JsonString "\"main_window\""), ("\"dimensions\"", array)]) :: JsonValue
+        let object2 = JsonObject (M.fromList [("\"debug\"", JsonString "\"on\""), ("\"window\"", object1)]) :: JsonValue
+        let object3 = JsonObject (M.fromList [("\"widget\"", object2)]) :: JsonValue
+        (                                                                                                         jsonValueAt) cursor `shouldBe` Just (object3                      :: JsonValue)
+        (fc                                                                                                   >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"widget\""      :: JsonValue)
+        (fc >=> ns                                                                                            >=> jsonValueAt) cursor `shouldBe` Just (object2                      :: JsonValue)
+        (fc >=> ns >=> fc                                                                                     >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"debug\""       :: JsonValue)
+        (fc >=> ns >=> fc >=> ns                                                                              >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"on\""          :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns                                                                       >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"window\""      :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns                                                                >=> jsonValueAt) cursor `shouldBe` Just (object1                      :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                                                         >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"name\""        :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns                                                  >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"main_window\"" :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns                                           >=> jsonValueAt) cursor `shouldBe` Just (JsonString "\"dimensions\""  :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns                                    >=> jsonValueAt) cursor `shouldBe` Just (array                        :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                             >=> jsonValueAt) cursor `shouldBe` Just (JsonNumber "500"             :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns                      >=> jsonValueAt) cursor `shouldBe` Just (JsonNumber "600.01e-02"      :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns               >=> jsonValueAt) cursor `shouldBe` Just (JsonBool True                :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns        >=> jsonValueAt) cursor `shouldBe` Just (JsonBool False               :: JsonValue)
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ns >=> jsonValueAt) cursor `shouldBe` Just (JsonNull                     :: JsonValue)
+      it "can navigate down and forwards" $ do
+        (                                                                      jsonTypeAt) cursor `shouldBe` Just JsonTypeObject
+        (fc                                                                >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns                                                         >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeObject
+        (fc >=> ns >=> fc                                                  >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns                                           >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns >=> ns                                    >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns                             >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeObject
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                      >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns               >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns        >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeString
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> jsonTypeAt) cursor `shouldBe` Just JsonTypeArray
+      it "can navigate up" $ do
+        (                                                                      pn) cursor `shouldBe` Nothing
+        (fc                                                                >=> pn) cursor `shouldBe`                                    Just cursor
+        (fc >=> ns                                                         >=> pn) cursor `shouldBe`                                    Just cursor
+        (fc >=> ns >=> fc                                                  >=> pn) cursor `shouldBe` (fc >=> ns                            ) cursor
+        (fc >=> ns >=> fc >=> ns                                           >=> pn) cursor `shouldBe` (fc >=> ns                            ) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns                                    >=> pn) cursor `shouldBe` (fc >=> ns                            ) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns                             >=> pn) cursor `shouldBe` (fc >=> ns                            ) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                      >=> pn) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns               >=> pn) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns        >=> pn) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> pn) cursor `shouldBe` (fc >=> ns >=> fc >=> ns >=> ns >=> ns) cursor
+      it "can get subtree size" $ do
+        (                                                                      ss) cursor `shouldBe` Just 16
+        (fc                                                                >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns                                                         >=> ss) cursor `shouldBe` Just 14
+        (fc >=> ns >=> fc                                                  >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns                                           >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns >=> ns                                    >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns                             >=> ss) cursor `shouldBe` Just 10
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                      >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns               >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns        >=> ss) cursor `shouldBe` Just 1
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> ss) cursor `shouldBe` Just 6
+      it "can get token at cursor" $ do
+        (jsonTokenAt                                                                      ) cursor `shouldBe` Just (JsonTokenBraceL                 )
+        (fc                                                                >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "widget"      )
+        (fc >=> ns                                                         >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenBraceL                 )
+        (fc >=> ns >=> fc                                                  >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "debug"       )
+        (fc >=> ns >=> fc >=> ns                                           >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "on"          )
+        (fc >=> ns >=> fc >=> ns >=> ns                                    >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "window"      )
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns                             >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenBraceL                 )
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc                      >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "name"        )
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns               >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "main_window" )
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns        >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenString   "dimensions"  )
+        (fc >=> ns >=> fc >=> ns >=> ns >=> ns >=> fc >=> ns >=> ns >=> ns >=> jsonTokenAt) cursor `shouldBe` Just (JsonTokenBracketL               )
diff --git a/test/data/sample.json b/test/data/sample.json
deleted file mode 100644
--- a/test/data/sample.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-    "widget": {
-        "debug": "on",
-        "window": {
-            "title": "Sample Konfabulator Widget",
-            "name": "main_window",
-            "width": 500,
-            "height": 500
-        },
-        "image": {
-            "src": "Images/Sun.png",
-            "name": "sun1",
-            "hOffset": 250,
-            "vOffset": 250,
-            "alignment": "center"
-        },
-        "text": {
-            "data": "Click Here",
-            "size": 36,
-            "style": "bold",
-            "name": "text1",
-            "hOffset": 250,
-            "vOffset": 100,
-            "alignment": "center",
-            "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
-        }
-    }
-}
