diff --git a/bench/Main.hs b/bench/Main.hs
new file mode 100644
--- /dev/null
+++ b/bench/Main.hs
@@ -0,0 +1,53 @@
+{-# LANGUAGE BangPatterns        #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+module Main where
+
+import Criterion.Main
+import Data.Monoid
+import Data.Word
+import Foreign
+import HaskellWorks.Data.FromForeignRegion
+
+import qualified Data.ByteString          as BS
+import qualified Data.ByteString.Internal as BSI
+import qualified Data.Vector.Storable     as DVS
+import qualified System.IO                as IO
+import qualified System.IO.MMap           as IO
+
+setupEnvByteString :: FilePath -> IO BS.ByteString
+setupEnvByteString filepath = do
+  (fptr :: ForeignPtr Word8, offset, size) <- IO.mmapFileForeignPtr filepath IO.ReadOnly Nothing
+  let !bs = BSI.fromForeignPtr (castForeignPtr fptr) offset size
+  return bs
+
+mmapVectorLike :: FromForeignRegion a => FilePath -> IO a
+mmapVectorLike filePath = do
+  region <- IO.mmapFileForeignPtr filePath IO.ReadOnly Nothing
+  let !bs = fromForeignRegion region
+  return bs
+
+sumFileByteString :: FilePath -> IO ()
+sumFileByteString filePath = do
+  !(bs :: BS.ByteString) <- mmapVectorLike filePath
+  IO.hPutStrLn IO.stderr $ "Length ByteString: " <> show (BS.length bs)
+  let !_ = BS.foldl' (+) 0 bs
+  return ()
+
+sumFileVectorWord64 :: FilePath -> IO ()
+sumFileVectorWord64 filePath = do
+  !(v :: DVS.Vector Word64) <- mmapVectorLike filePath
+  IO.hPutStrLn IO.stderr $ "Length Vector: " <> show (DVS.length v)
+  let !_ = DVS.foldl' (+) 0 v
+  return ()
+
+benchRankJson40Conduits :: [Benchmark]
+benchRankJson40Conduits =
+  [ env (return ()) $ \_ -> bgroup "medium.csv"
+    [ bench "Foldl' over ByteString"    (whnfIO (sumFileByteString   "corpus/medium.csv"))
+    , bench "Foldl' over Vector Word64" (whnfIO (sumFileVectorWord64 "corpus/medium.csv"))
+    ]
+  ]
+
+main :: IO ()
+main = defaultMain benchRankJson40Conduits
diff --git a/hw-prim.cabal b/hw-prim.cabal
--- a/hw-prim.cabal
+++ b/hw-prim.cabal
@@ -1,64 +1,111 @@
-name:                   hw-prim
-version:                0.5.0.0
-synopsis:               Primitive functions and data types
-description:            Please see README.md
-homepage:               http://github.com/haskell-works/hw-prim#readme
-license:                BSD3
-license-file:           LICENSE
-author:                 John Ky
-maintainer:             newhoggy@gmail.com
-copyright:              2016 John Ky
-category:               Data
-stability:              Experimental
-build-type:             Simple
-extra-source-files:     README.md
-cabal-version:          >= 1.22
-
-library
-  hs-source-dirs:       src
-  exposed-modules:      HaskellWorks.Data.AtIndex
-                      , HaskellWorks.Data.ByteString
-                      , HaskellWorks.Data.Char.IsChar
-                      , HaskellWorks.Data.Concat
-                      , HaskellWorks.Data.Container
-                      , HaskellWorks.Data.Drop
-                      , HaskellWorks.Data.Empty
-                      , HaskellWorks.Data.Filter
-                      , HaskellWorks.Data.FromByteString
-                      , HaskellWorks.Data.FromForeignRegion
-                      , HaskellWorks.Data.Generate
-                      , HaskellWorks.Data.Head
-                      , HaskellWorks.Data.Length
-                      , HaskellWorks.Data.Naive
-                      , HaskellWorks.Data.Positioning
-                      , HaskellWorks.Data.Search
-                      , HaskellWorks.Data.Take
-                      , HaskellWorks.Data.TreeCursor
-                      , HaskellWorks.Data.Uncons
-                      , HaskellWorks.Data.Unsign
-                      , HaskellWorks.Data.Vector.AsVector64
-  build-depends:        base                          >= 4          && < 5
-                      , bytestring
-                      , vector
+-- This file has been generated from package.yaml by hpack version 0.20.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 4f88cd2fa46a5092fcd354ac1e47e7d3ea5d71eda338aaa197c9ec5c1ecb9afe
 
-  default-language:     Haskell2010
-  ghc-options:          -Wall -O2 -msse4.2
+name:           hw-prim
+version:        0.5.0.1
+synopsis:       Primitive functions and data types
+description:    Please see README.md
+category:       Data
+stability:      Experimental
+homepage:       http://github.com/haskell-works/hw-prim#readme
+bug-reports:    https://github.com/haskell-works/hw-prim/issues
+author:         John Ky
+maintainer:     newhoggy@gmail.com
+copyright:      2016-2018 John Ky
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+cabal-version:  >= 1.10
 
-test-suite hw-prim-test
-  type:                 exitcode-stdio-1.0
-  hs-source-dirs:       test
-  main-is:              Spec.hs
-  other-modules:        HaskellWorks.Data.FromByteStringSpec
-                      , HaskellWorks.Data.SearchSpec
-  build-depends:        base                          >= 4          && < 5
-                      , bytestring
-                      , hspec
-                      , hw-prim
-                      , QuickCheck
-                      , vector
-  ghc-options:          -threaded -rtsopts -with-rtsopts=-N -Wall
-  default-language:     Haskell2010
+extra-source-files:
+    README.md
 
 source-repository head
-  type:     git
+  type: git
   location: https://github.com/haskell-works/hw-prim
+
+library
+  hs-source-dirs:
+      src
+  ghc-options: -Wall -O2 -msse4.2
+  build-depends:
+      base >=4 && <5
+    , bytestring
+    , mmap
+    , vector
+  exposed-modules:
+      HaskellWorks.Data.AtIndex
+      HaskellWorks.Data.ByteString
+      HaskellWorks.Data.Char.IsChar
+      HaskellWorks.Data.Concat
+      HaskellWorks.Data.Container
+      HaskellWorks.Data.Decode
+      HaskellWorks.Data.Drop
+      HaskellWorks.Data.Empty
+      HaskellWorks.Data.Filter
+      HaskellWorks.Data.FromByteString
+      HaskellWorks.Data.FromForeignRegion
+      HaskellWorks.Data.Generate
+      HaskellWorks.Data.Head
+      HaskellWorks.Data.Length
+      HaskellWorks.Data.Naive
+      HaskellWorks.Data.Positioning
+      HaskellWorks.Data.Search
+      HaskellWorks.Data.Sign
+      HaskellWorks.Data.Snoc
+      HaskellWorks.Data.Take
+      HaskellWorks.Data.TreeCursor
+      HaskellWorks.Data.Uncons
+      HaskellWorks.Data.Unsign
+      HaskellWorks.Data.Vector.AsVector64
+      HaskellWorks.Data.Vector.BoxedVectorLike
+      HaskellWorks.Data.Vector.StorableVectorLike
+  other-modules:
+      HaskellWorks.Data.Char
+      Paths_hw_prim
+  default-language: Haskell2010
+
+test-suite hw-prim-test
+  type: exitcode-stdio-1.0
+  main-is: Spec.hs
+  hs-source-dirs:
+      test
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
+  build-depends:
+      QuickCheck
+    , base >=4 && <5
+    , bytestring
+    , directory
+    , exceptions
+    , hedgehog
+    , hspec
+    , hw-hspec-hedgehog
+    , hw-prim
+    , mmap
+    , vector
+  other-modules:
+      HaskellWorks.Data.FromByteStringSpec
+      HaskellWorks.Data.FromForeignRegionSpec
+      HaskellWorks.Data.SearchSpec
+      Paths_hw_prim
+  default-language: Haskell2010
+
+benchmark bench
+  type: exitcode-stdio-1.0
+  main-is: Main.hs
+  hs-source-dirs:
+      bench
+  ghc-options: -Wall -O2 -msse4.2
+  build-depends:
+      base >=4 && <5
+    , bytestring
+    , criterion
+    , hw-prim
+    , mmap
+    , vector
+  other-modules:
+      Paths_hw_prim
+  default-language: Haskell2010
diff --git a/src/HaskellWorks/Data/AtIndex.hs b/src/HaskellWorks/Data/AtIndex.hs
--- a/src/HaskellWorks/Data/AtIndex.hs
+++ b/src/HaskellWorks/Data/AtIndex.hs
@@ -1,27 +1,23 @@
-{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE FlexibleInstances   #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
-{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE TypeFamilies        #-}
 
 module HaskellWorks.Data.AtIndex
-    ( AtIndex(..)
-    , Container(..)
+    ( Container(..)
+    , AtIndex(..)
     , Length(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Length
-import HaskellWorks.Data.Positioning
-
-import qualified Data.ByteString      as BS
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Length
+import           HaskellWorks.Data.Positioning
 
 class Length v => AtIndex v where
-  -- | Element at the given index
   (!!!)   :: v -> Position -> Elem v
-
-  -- | Element at the given index
   atIndex :: v -> Position -> Elem v
 
 instance AtIndex [a] where
diff --git a/src/HaskellWorks/Data/Char.hs b/src/HaskellWorks/Data/Char.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Char.hs
@@ -0,0 +1,5 @@
+module HaskellWorks.Data.Char
+  ( module X
+  ) where
+
+import HaskellWorks.Data.Char.IsChar as X
diff --git a/src/HaskellWorks/Data/Concat.hs b/src/HaskellWorks/Data/Concat.hs
--- a/src/HaskellWorks/Data/Concat.hs
+++ b/src/HaskellWorks/Data/Concat.hs
@@ -6,16 +6,15 @@
   ( Concat(..)
   ) where
 
-import Data.Int
-import Data.Word
-
-import qualified Data.ByteString      as BS
-import qualified Data.List            as L
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
 
+-- | Class of values that support vector like operations
 class Concat v where
-  -- | Concatenate list of values
   concat :: [v] -> v
 
 instance Concat [a] where
diff --git a/src/HaskellWorks/Data/Container.hs b/src/HaskellWorks/Data/Container.hs
--- a/src/HaskellWorks/Data/Container.hs
+++ b/src/HaskellWorks/Data/Container.hs
@@ -6,15 +6,13 @@
     ( Container(..)
     ) where
 
-import Data.Int
-import Data.Word
-
-import qualified Data.ByteString      as BS
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
 
 class Container a where
-  -- | Element type of a container
   type Elem a
 
 instance Container [a] where
diff --git a/src/HaskellWorks/Data/Decode.hs b/src/HaskellWorks/Data/Decode.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Decode.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module HaskellWorks.Data.Decode
+  ( Decode(..)
+  , DecodeError(..)
+  ) where
+
+data DecodeError = DecodeError String deriving (Eq, Show)
+
+class Decode s t where
+  decode :: s -> Either DecodeError t
diff --git a/src/HaskellWorks/Data/Drop.hs b/src/HaskellWorks/Data/Drop.hs
--- a/src/HaskellWorks/Data/Drop.hs
+++ b/src/HaskellWorks/Data/Drop.hs
@@ -7,19 +7,17 @@
     , Drop(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Container
-import HaskellWorks.Data.Positioning
-import Prelude                       hiding (drop)
-
-import qualified Data.ByteString      as BS
-import qualified Data.List            as L
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
+import           Prelude hiding (drop)
 
 class Container v => Drop v where
-  -- | Drop the first element from the container
   drop :: Count -> v -> v
 
 instance Drop [a] where
diff --git a/src/HaskellWorks/Data/Empty.hs b/src/HaskellWorks/Data/Empty.hs
--- a/src/HaskellWorks/Data/Empty.hs
+++ b/src/HaskellWorks/Data/Empty.hs
@@ -7,16 +7,14 @@
     ( Empty(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Container
-
-import qualified Data.ByteString      as BS
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
 
 class Container a => Empty a where
-  -- | Empty container
   empty :: a
 
 instance Empty [a] where
diff --git a/src/HaskellWorks/Data/Filter.hs b/src/HaskellWorks/Data/Filter.hs
--- a/src/HaskellWorks/Data/Filter.hs
+++ b/src/HaskellWorks/Data/Filter.hs
@@ -15,8 +15,8 @@
 import           Data.Word
 import           HaskellWorks.Data.Container
 
+-- | Class of values that support vector like operations
 class Container v => Filter v where
-  -- | Filter the element of a container with the given predicate
   filter :: (Elem v -> Bool) -> v -> v
 
 instance Filter String where
diff --git a/src/HaskellWorks/Data/FromByteString.hs b/src/HaskellWorks/Data/FromByteString.hs
--- a/src/HaskellWorks/Data/FromByteString.hs
+++ b/src/HaskellWorks/Data/FromByteString.hs
@@ -1,16 +1,16 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE InstanceSigs      #-}
+{-# LANGUAGE FlexibleInstances  #-}
+{-# LANGUAGE InstanceSigs       #-}
 
 module HaskellWorks.Data.FromByteString
   ( FromByteString(..)
   ) where
 
-import Data.Bits
-import Data.Word
-
-import qualified Data.ByteString      as BS
-import qualified Data.Vector.Storable as DVS
+import           Data.Bits
+import qualified Data.ByteString            as BS
+import qualified Data.Vector.Storable       as DVS
+import           Data.Word
 
+-- | Class for byte-string-like datastructures
 class FromByteString a where
   -- | Convert a byte string to a value of type @a
   fromByteString :: BS.ByteString -> a
@@ -20,47 +20,47 @@
   fromByteString bs = DVS.unfoldrN (BS.length bs) gen bs
     where gen :: BS.ByteString -> Maybe (Word8, BS.ByteString)
           gen cs = case BS.uncons cs of
-            Just (d, ds) -> Just (d, ds)
-            Nothing      -> Nothing
+            Just (d, ds)  -> Just (d, ds)
+            Nothing       -> Nothing
 
 instance FromByteString (DVS.Vector Word16) where
   fromByteString :: BS.ByteString -> DVS.Vector Word16
   fromByteString bs = DVS.unfoldrN (BS.length bs `div` 2 + 2) gen bs
     where gen :: BS.ByteString -> Maybe (Word16, BS.ByteString)
           gen cs = case BS.uncons cs of
-            Just (d, ds) -> gen' 8 (fromIntegral d) ds
-            Nothing      -> Nothing
+            Just (d, ds)  -> gen' 8 (fromIntegral d) ds
+            Nothing       -> Nothing
           gen' :: Int -> Word16 -> BS.ByteString -> Maybe (Word16, BS.ByteString)
           gen' n w cs
             | n >= 16   = Just (w, cs)
             | otherwise = case BS.uncons cs of
-                Just (d, ds) -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
-                Nothing      -> Just (w, cs)
+                Just (d, ds)  -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
+                Nothing       -> Just (w, cs)
 
 instance FromByteString (DVS.Vector Word32) where
   fromByteString :: BS.ByteString -> DVS.Vector Word32
   fromByteString bs = DVS.unfoldrN (BS.length bs `div` 4 + 4) gen bs
     where gen :: BS.ByteString -> Maybe (Word32, BS.ByteString)
           gen cs = case BS.uncons cs of
-            Just (d, ds) -> gen' 8 (fromIntegral d) ds
-            Nothing      -> Nothing
+            Just (d, ds)  -> gen' 8 (fromIntegral d) ds
+            Nothing       -> Nothing
           gen' :: Int -> Word32 -> BS.ByteString -> Maybe (Word32, BS.ByteString)
           gen' n w cs
             | n >= 32   = Just (w, cs)
             | otherwise = case BS.uncons cs of
-                Just (d, ds) -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
-                Nothing      -> Just (w, cs)
+                Just (d, ds)  -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
+                Nothing       -> Just (w, cs)
 
 instance FromByteString (DVS.Vector Word64) where
   fromByteString :: BS.ByteString -> DVS.Vector Word64
   fromByteString bs = DVS.unfoldrN (BS.length bs `div` 8 + 8) gen bs
     where gen :: BS.ByteString -> Maybe (Word64, BS.ByteString)
           gen cs = case BS.uncons cs of
-            Just (d, ds) -> gen' 8 (fromIntegral d) ds
-            Nothing      -> Nothing
+            Just (d, ds)  -> gen' 8 (fromIntegral d) ds
+            Nothing       -> Nothing
           gen' :: Int -> Word64 -> BS.ByteString -> Maybe (Word64, BS.ByteString)
           gen' n w cs
             | n >= 64   = Just (w, cs)
             | otherwise = case BS.uncons cs of
-                Just (d, ds) -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
-                Nothing      -> Just (w, cs)
+                Just (d, ds)  -> gen' (n + 8) (w .|. (fromIntegral d `shiftL` fromIntegral n)) ds
+                Nothing       -> Just (w, cs)
diff --git a/src/HaskellWorks/Data/FromForeignRegion.hs b/src/HaskellWorks/Data/FromForeignRegion.hs
--- a/src/HaskellWorks/Data/FromForeignRegion.hs
+++ b/src/HaskellWorks/Data/FromForeignRegion.hs
@@ -1,17 +1,23 @@
+{-# LANGUAGE BangPatterns      #-}
 {-# LANGUAGE FlexibleInstances #-}
 
-module HaskellWorks.Data.FromForeignRegion where
+module HaskellWorks.Data.FromForeignRegion
+  ( FromForeignRegion(..)
+  , ForeignRegion
+  , mmapFromForeignRegion
+  ) where
 
 import Data.Word
 import Foreign.ForeignPtr
-import HaskellWorks.Data.FromByteString
 
 import qualified Data.ByteString          as BS
 import qualified Data.ByteString.Internal as BSI
 import qualified Data.Vector.Storable     as DVS
+import qualified System.IO.MMap           as IO
 
 type ForeignRegion = (ForeignPtr Word8, Int, Int)
 
+-- | Class for datastructures that can be created from a foreign region
 class FromForeignRegion a where
   -- | Create a value of type @a from a foreign region.
   fromForeignRegion :: ForeignRegion -> a
@@ -20,13 +26,19 @@
   fromForeignRegion (fptr, offset, size) = BSI.fromForeignPtr (castForeignPtr fptr) offset size
 
 instance FromForeignRegion (DVS.Vector Word8) where
-  fromForeignRegion = fromByteString . fromForeignRegion
+  fromForeignRegion (fptr, offset, size) = DVS.unsafeFromForeignPtr (castForeignPtr fptr) offset size
 
 instance FromForeignRegion (DVS.Vector Word16) where
-  fromForeignRegion = fromByteString . fromForeignRegion
+  fromForeignRegion (fptr, offset, size) = DVS.unsafeFromForeignPtr (castForeignPtr fptr) offset ((size + 1) `div` 2)
 
 instance FromForeignRegion (DVS.Vector Word32) where
-  fromForeignRegion = fromByteString . fromForeignRegion
+  fromForeignRegion (fptr, offset, size) = DVS.unsafeFromForeignPtr (castForeignPtr fptr) offset ((size + 3) `div` 4)
 
 instance FromForeignRegion (DVS.Vector Word64) where
-  fromForeignRegion = fromByteString . fromForeignRegion
+  fromForeignRegion (fptr, offset, size) = DVS.unsafeFromForeignPtr (castForeignPtr fptr) offset ((size + 7) `div` 8)
+
+mmapFromForeignRegion :: FromForeignRegion a => FilePath -> IO a
+mmapFromForeignRegion filePath = do
+  region <- IO.mmapFileForeignPtr filePath IO.ReadOnly Nothing
+  let !bs = fromForeignRegion region
+  return bs
diff --git a/src/HaskellWorks/Data/Generate.hs b/src/HaskellWorks/Data/Generate.hs
--- a/src/HaskellWorks/Data/Generate.hs
+++ b/src/HaskellWorks/Data/Generate.hs
@@ -7,17 +7,15 @@
   , Generate(..)
   ) where
 
-import           Data.Int
-import           Data.Word
-import           HaskellWorks.Data.Container
-
 import qualified Data.ByteString               as BS
+import           Data.Int
 import qualified Data.Vector                   as DV
 import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
 
+-- | Class of values that support vector like operations
 class Container v => Generate v where
-  -- | Generate a container of the given size using element produced by the
-  -- provided function.
   generate :: Int -> (Int -> Elem v) -> v
 
 instance Generate String where
diff --git a/src/HaskellWorks/Data/Head.hs b/src/HaskellWorks/Data/Head.hs
--- a/src/HaskellWorks/Data/Head.hs
+++ b/src/HaskellWorks/Data/Head.hs
@@ -7,18 +7,16 @@
     , Head(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Container
-import Prelude                     hiding (head)
-
-import qualified Data.ByteString      as BS
-import qualified Data.List            as L
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           Prelude hiding (head)
 
 class Container v => Head v where
-  -- | The first element of the container.
   head :: v -> Elem v
 
 instance Head [a] where
diff --git a/src/HaskellWorks/Data/Length.hs b/src/HaskellWorks/Data/Length.hs
--- a/src/HaskellWorks/Data/Length.hs
+++ b/src/HaskellWorks/Data/Length.hs
@@ -1,27 +1,23 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# LANGUAGE TypeFamilies      #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE TypeFamilies          #-}
 
 module HaskellWorks.Data.Length
     ( Container(..)
     , Length(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Container
-import HaskellWorks.Data.Positioning
-import Prelude                       hiding (length)
-
-import qualified Data.ByteString      as BS
-import qualified Data.List            as L
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
+import           Prelude hiding (length)
 
 class Container v => Length v where
-  -- | The length of the container
   length :: v -> Count
-
-  -- | The length of the container given as a position
   end :: v -> Position
   end = fromIntegral . length
   {-# INLINE end #-}
diff --git a/src/HaskellWorks/Data/Naive.hs b/src/HaskellWorks/Data/Naive.hs
--- a/src/HaskellWorks/Data/Naive.hs
+++ b/src/HaskellWorks/Data/Naive.hs
@@ -3,8 +3,6 @@
     , naive
     ) where
 
--- | Data type providing reference implementations of typeclasses.  Such
--- implementations may be inefficient.
 newtype Naive a = Naive a deriving (Eq, Show)
 
 naive :: Naive a -> a
diff --git a/src/HaskellWorks/Data/Sign.hs b/src/HaskellWorks/Data/Sign.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Sign.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE TypeFamilies #-}
+
+module HaskellWorks.Data.Sign
+    ( Sign(..)
+    ) where
+
+import Data.Int
+import Data.Word
+
+class Sign a where
+  type SignOf a
+  sign :: a -> SignOf a
+
+instance Sign Word where
+  type SignOf Word = Int
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Word8 where
+  type SignOf Word8 = Int8
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Word16 where
+  type SignOf Word16 = Int16
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Word32 where
+  type SignOf Word32 = Int32
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Word64 where
+  type SignOf Word64 = Int64
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Int where
+  type SignOf Int = Int
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Int8 where
+  type SignOf Int8 = Int8
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Int16 where
+  type SignOf Int16 = Int16
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Int32 where
+  type SignOf Int32 = Int32
+  sign = fromIntegral
+  {-# INLINE sign #-}
+
+instance Sign Int64 where
+  type SignOf Int64 = Int64
+  sign = fromIntegral
+  {-# INLINE sign #-}
diff --git a/src/HaskellWorks/Data/Snoc.hs b/src/HaskellWorks/Data/Snoc.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Snoc.hs
@@ -0,0 +1,93 @@
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE TypeFamilies          #-}
+
+module HaskellWorks.Data.Snoc
+    ( Snoc(..)
+    ) where
+
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+
+class Container v => Snoc v where
+  snoc :: v -> Elem v -> v
+
+instance Snoc [a] where
+  snoc v a = v ++ [a]
+  {-# INLINE snoc #-}
+
+instance Snoc BS.ByteString where
+  snoc = BS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Word8) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Word16) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Word32) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Word64) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Word8) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Word16) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Word32) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Word64) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Int8) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Int16) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Int32) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DV.Vector Int64) where
+  snoc = DV.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Int8) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Int16) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Int32) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Int64) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
+
+instance Snoc (DVS.Vector Int) where
+  snoc = DVS.snoc
+  {-# INLINE snoc #-}
diff --git a/src/HaskellWorks/Data/Take.hs b/src/HaskellWorks/Data/Take.hs
--- a/src/HaskellWorks/Data/Take.hs
+++ b/src/HaskellWorks/Data/Take.hs
@@ -7,18 +7,16 @@
     , Take(..)
     ) where
 
-import Data.Int
-import Data.Word
-import HaskellWorks.Data.Container
-import HaskellWorks.Data.Positioning
-
-import qualified Data.ByteString      as BS
-import qualified Data.List            as L
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import qualified Data.List                     as L
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Positioning
 
 class Container v => Take v where
-  -- | Take the first n elements from a container
   take :: Count -> v -> v
 
 instance Take [a] where
diff --git a/src/HaskellWorks/Data/TreeCursor.hs b/src/HaskellWorks/Data/TreeCursor.hs
--- a/src/HaskellWorks/Data/TreeCursor.hs
+++ b/src/HaskellWorks/Data/TreeCursor.hs
@@ -1,8 +1,13 @@
+-- |
+-- Copyright: 2016 John Ky
+-- License: MIT
+--
+-- Tree Cursor
 module HaskellWorks.Data.TreeCursor
     ( TreeCursor(..)
     ) where
 
-import HaskellWorks.Data.Positioning
+import           HaskellWorks.Data.Positioning
 
 class TreeCursor k where
   firstChild  :: k -> Maybe k
diff --git a/src/HaskellWorks/Data/Uncons.hs b/src/HaskellWorks/Data/Uncons.hs
--- a/src/HaskellWorks/Data/Uncons.hs
+++ b/src/HaskellWorks/Data/Uncons.hs
@@ -7,25 +7,23 @@
     , Uncons(..)
     ) where
 
-import Data.Int
-import Data.Maybe
-import Data.Word
-import HaskellWorks.Data.Container
-import HaskellWorks.Data.Drop
-import Prelude                     hiding (drop)
-
-import qualified Data.ByteString      as BS
-import qualified Data.Vector          as DV
-import qualified Data.Vector.Storable as DVS
+import qualified Data.ByteString               as BS
+import           Data.Int
+import           Data.Maybe
+import qualified Data.Vector                   as DV
+import qualified Data.Vector.Storable          as DVS
+import           Data.Word
+import           HaskellWorks.Data.Container
+import           HaskellWorks.Data.Drop
+import           Prelude hiding (drop)
 
 class Drop v => Uncons v where
-  -- | Uncons the head from the container
   uncons :: v -> Maybe (Elem v, v)
 
 instance Uncons String where
   uncons s = case s of
-    (x:xs) -> Just (x, xs)
-    _      -> Nothing
+    (x:xs)  -> Just (x, xs)
+    _       -> Nothing
   {-# INLINE uncons   #-}
 
 instance Uncons BS.ByteString where
diff --git a/src/HaskellWorks/Data/Unsign.hs b/src/HaskellWorks/Data/Unsign.hs
--- a/src/HaskellWorks/Data/Unsign.hs
+++ b/src/HaskellWorks/Data/Unsign.hs
@@ -8,10 +8,7 @@
 import Data.Word
 
 class Unsign a where
-  -- | The correspond unsigned version of a type
   type UnsignOf a
-
-  -- | Convert to an unsigned type
   unsign :: a -> UnsignOf a
 
 instance Unsign Int where
diff --git a/src/HaskellWorks/Data/Vector/BoxedVectorLike.hs b/src/HaskellWorks/Data/Vector/BoxedVectorLike.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Vector/BoxedVectorLike.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE AllowAmbiguousTypes   #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module HaskellWorks.Data.Vector.BoxedVectorLike
+  ( BoxedVectorLike(..)
+  ) where
+
+import qualified Data.Vector      as DV
+import           Data.Word
+import           Foreign.Storable
+
+-- | Class of values that support boxed vector like operations
+class BoxedVectorLike v e where
+  bImap :: (Int -> a -> b) -> v a -> v b
+  bMap :: (a -> b) -> v a -> v b
+  bUnfoldr :: (Storable a) => (b -> Maybe (a, b)) -> b -> v a
+  bUnfoldrN :: (Storable a) => Int -> (b -> Maybe (a, b)) -> b -> v a
+
+instance BoxedVectorLike DV.Vector Word8 where
+  bImap = DV.imap
+  bMap = DV.map
+  bUnfoldr = DV.unfoldr
+  bUnfoldrN = DV.unfoldrN
+  {-# INLINE bImap     #-}
+  {-# INLINE bMap      #-}
+  {-# INLINE bUnfoldr  #-}
+  {-# INLINE bUnfoldrN #-}
+
+instance BoxedVectorLike DV.Vector Word16 where
+  bImap = DV.imap
+  bMap = DV.map
+  bUnfoldr = DV.unfoldr
+  bUnfoldrN = DV.unfoldrN
+  {-# INLINE bImap     #-}
+  {-# INLINE bMap      #-}
+  {-# INLINE bUnfoldr  #-}
+  {-# INLINE bUnfoldrN #-}
+
+instance BoxedVectorLike DV.Vector Word32 where
+  bImap = DV.imap
+  bMap = DV.map
+  bUnfoldr = DV.unfoldr
+  bUnfoldrN = DV.unfoldrN
+  {-# INLINE bImap     #-}
+  {-# INLINE bMap      #-}
+  {-# INLINE bUnfoldr  #-}
+  {-# INLINE bUnfoldrN #-}
+
+instance BoxedVectorLike DV.Vector Word64 where
+  bImap = DV.imap
+  bMap = DV.map
+  bUnfoldr = DV.unfoldr
+  bUnfoldrN = DV.unfoldrN
+  {-# INLINE bImap     #-}
+  {-# INLINE bMap      #-}
+  {-# INLINE bUnfoldr  #-}
+  {-# INLINE bUnfoldrN #-}
diff --git a/src/HaskellWorks/Data/Vector/StorableVectorLike.hs b/src/HaskellWorks/Data/Vector/StorableVectorLike.hs
new file mode 100644
--- /dev/null
+++ b/src/HaskellWorks/Data/Vector/StorableVectorLike.hs
@@ -0,0 +1,58 @@
+{-# LANGUAGE AllowAmbiguousTypes   #-}
+{-# LANGUAGE FlexibleInstances     #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+
+module HaskellWorks.Data.Vector.StorableVectorLike
+  ( StorableVectorLike(..)
+  ) where
+
+import qualified Data.Vector.Storable as DVS
+import           Data.Word
+import           Foreign.Storable
+
+-- | Class of values that support storable vector like operations
+class StorableVectorLike v e where
+  sImap :: (Storable a, Storable b) => (Int -> a -> b) -> v a -> v b
+  sMap :: (Storable a, Storable b) => (a -> b) -> v a -> v b
+  sUnfoldr :: (Storable a) => (b -> Maybe (a, b)) -> b -> v a
+  sUnfoldrN :: (Storable a) => Int -> (b -> Maybe (a, b)) -> b -> v a
+
+instance StorableVectorLike DVS.Vector Word8 where
+  sImap = DVS.imap
+  sMap = DVS.map
+  sUnfoldr = DVS.unfoldr
+  sUnfoldrN = DVS.unfoldrN
+  {-# INLINABLE sImap     #-}
+  {-# INLINABLE sMap      #-}
+  {-# INLINABLE sUnfoldr  #-}
+  {-# INLINABLE sUnfoldrN #-}
+
+instance StorableVectorLike DVS.Vector Word16 where
+  sImap = DVS.imap
+  sMap = DVS.map
+  sUnfoldr = DVS.unfoldr
+  sUnfoldrN = DVS.unfoldrN
+  {-# INLINABLE sImap     #-}
+  {-# INLINABLE sMap      #-}
+  {-# INLINABLE sUnfoldr  #-}
+  {-# INLINABLE sUnfoldrN #-}
+
+instance StorableVectorLike DVS.Vector Word32 where
+  sImap = DVS.imap
+  sMap = DVS.map
+  sUnfoldr = DVS.unfoldr
+  sUnfoldrN = DVS.unfoldrN
+  {-# INLINABLE sImap     #-}
+  {-# INLINABLE sMap      #-}
+  {-# INLINABLE sUnfoldr  #-}
+  {-# INLINABLE sUnfoldrN #-}
+
+instance StorableVectorLike DVS.Vector Word64 where
+  sImap = DVS.imap
+  sMap = DVS.map
+  sUnfoldr = DVS.unfoldr
+  sUnfoldrN = DVS.unfoldrN
+  {-# INLINABLE sImap     #-}
+  {-# INLINABLE sMap      #-}
+  {-# INLINABLE sUnfoldr  #-}
+  {-# INLINABLE sUnfoldrN #-}
diff --git a/test/HaskellWorks/Data/FromForeignRegionSpec.hs b/test/HaskellWorks/Data/FromForeignRegionSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/HaskellWorks/Data/FromForeignRegionSpec.hs
@@ -0,0 +1,40 @@
+{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
+{-# LANGUAGE BangPatterns               #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE OverloadedLists            #-}
+{-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE StandaloneDeriving         #-}
+
+module HaskellWorks.Data.FromForeignRegionSpec (spec) where
+
+import Control.Monad.IO.Class
+import Data.Word
+import Data.Word
+import HaskellWorks.Data.FromByteString
+import HaskellWorks.Data.FromForeignRegion
+import HaskellWorks.Hspec.Hedgehog
+import Hedgehog
+import Hedgehog.Internal.Gen
+import Test.Hspec
+
+import qualified Data.ByteString                     as BS
+import qualified Data.Vector.Storable                as DVS
+import qualified HaskellWorks.Data.FromForeignRegion as IO
+import qualified Hedgehog.Gen                        as G
+import qualified Hedgehog.Range                      as R
+import qualified System.Directory                    as IO
+import qualified System.IO                           as IO
+
+{-# ANN module ("HLint: Ignore Redundant do" :: String) #-}
+
+spec :: Spec
+spec = describe "HaskellWorks.Data.FromForeignRegionSpec" $ do
+  it "Be able to load file into Vector" $ requireProperty $ do
+    ws <- forAll $ G.list (R.linear 0 (1024 * 16)) (G.word8 R.constantBounded)
+    liftIO $ IO.createDirectoryIfMissing True "./tmp"
+    (fp, h) <- liftIO $ IO.openBinaryTempFile "./tmp" "property-test-.txt"
+    liftIO $ BS.hPut h (BS.pack ws)
+    liftIO $ IO.hClose h
+    !(_ :: DVS.Vector Word64) <- liftIO $ IO.mmapFromForeignRegion fp
+    liftIO $ IO.removeFile fp
+    True === True
