diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,11 @@
 # Change Log
 
+## [1.2.0.0] - 2018-12-05
+
+- Add ``Hashable`` instances
+- Generalize ``concatMap``
+- Various code and documentation cleanup
+
 ## [1.1.1.0] - 2018-11-13
 
 - Fix build and add CI for 8.6.2
diff --git a/readme.md b/readme.md
--- a/readme.md
+++ b/readme.md
@@ -1,21 +1,45 @@
-# Vector Sized
+# ``vector-sized`` [![Hackage][hackage-shield]][hackage]
 
-This package exports a newtype tagging the vectors from the
-[vector](https://hackage.haskell.org/package/vector) package with a type level
-natural representing their size.
-It also exports a few functions from vector appropriately retyped.
+This package exports a newtype tagging the vectors from the [``vector``][1]
+package with a type-level natural representing their sized. It also exports
+functions from ``vector`` whose size can be determined ahead of time,
+appropriately retyped.
 
-This package is fairly similar to
-the [fixed-vector](https://hackage.haskell.org/package/fixed-vector) package.
-While both provide vectors of statically know length they use completely
-different implementation with different tradeoffs. `vector-sized` is a newtype
-wrapper over `vector` thus it's able to handle vectors of arbitrary length but
-have to carry runtime representation of length which is significant memory
-overhead for small vectors. `fixed-vector` defines all functions as
-manipulations of Church-encoded product types (`∀r. (a→a→r) → r` for 2D vectors)
-so it can work for both arbitrary product types like `data V2 a = V2 a a` and
-opaque length-parametrized vectors provided by library. As consequence of
-implementation it can't handle vectors larger than tens of elements.
+Currently, we provide size-tagged versions of the following:
 
+* [``Data.Vector.Vector``][2], in ``Data.Vector.Sized``
+* [``Data.Vector.Generic.Vector``][5], in ``Data.Vector.Generic.Sized``
+* [``Data.Vector.Storable.Vector``][3], in ``Data.Vector.Storable.Sized``
+* [``Data.Vector.Unboxed.Vector``][4], in ``Data.Vector.Unboxed.Sized``
 
-The initial code for this package was written by @bgamari in a [PR for vulkan](https://github.com/expipiplus1/vulkan/pull/1)
+We also provide mutable versions of each of the above. Additionally, we include
+functions for converting to and from 'unsized' vectors and lists, using
+CPS-style existentials.
+
+The code in this package is based on the initial work by Ben Gamari in a [PR for
+``vulkan``][7].
+
+## How is this different to ``fixed-vector``?
+
+This package is fairly similar to [``fixed-vector``][6], as both libraries are
+designed to provide vectors of statically known length. However, the
+implementations used are different, with different tradeoffs. ``vector-sized``
+uses a newtype wrapper around vectors from ``vector``, and is thus able to
+handle vectors of arbitrary length. However, this approach requires us to carry
+a runtime representation of length, which is a significant memory overhead for
+small vectors. ``fixed-vector`` instead defines all functions as manipulations
+of Church-encoded product types of the form ``∀r. (a → a → r) → r`` (for 2D
+vectors), allowing it to work for both arbitrary product types (like ``data V2 a
+= V2 a a``) and opaque length-parameterized vectors. However, as a consequence
+of this implementation choice, ``fixed-vector`` cannot handle vectors whose size
+exceeds tens of elements.
+
+[1]: https://hackage.haskell.org/package/vector
+[2]: https://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector.html#t:Vector
+[3]: https://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector-Storable.html#t:Vector
+[4]: https://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector-Unboxed.html#t:Vector
+[5]: https://hackage.haskell.org/package/vector-0.12.0.1/docs/Data-Vector-Generic.html#t:Vector  
+[6]: https://hackage.haskell.org/package/fixed-vector
+[7]: https://github.com/expipiplus1/vulkan/pull/1
+[hackage-shield]: https://img.shields.io/badge/hackage-v1.1.10-blue.svg
+[hackage]: http://hackage.haskell.org/package/vector-sized
diff --git a/src/Data/Vector/Generic/Mutable/Sized.hs b/src/Data/Vector/Generic/Mutable/Sized.hs
--- a/src/Data/Vector/Generic/Mutable/Sized.hs
+++ b/src/Data/Vector/Generic/Mutable/Sized.hs
@@ -9,13 +9,13 @@
 
 {-|
 This module reexports the functionality in 'Data.Vector.Generic.Mutable'
-which maps well to explicity sized vectors.
+which maps well to explicitly sized vectors.
 
 Functions returning a vector determine the size from the type context
 unless they have a @'@ suffix in which case they take an explicit 'Proxy'
 argument.
 
-Functions where the resultant vector size is not know until compile time
+Functions where the resultant vector size is not known until runtime
 are not exported.
 -}
 
@@ -111,7 +111,7 @@
 length' _ = Proxy
 {-# inline length' #-}
 
--- | /O(1)/ Check whether the mutable vector is empty
+-- | /O(1)/ Check whether the mutable vector is empty.
 null :: forall v n s a. KnownNat n
        => MVector v n s a -> Bool
 null _ = isJust $ Proxy @n `sameNat` Proxy @0
@@ -155,8 +155,8 @@
 tail (MVector v) = MVector (VGM.unsafeTail v)
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall v n k s a. (KnownNat n, VGM.MVector v a)
      => MVector v (n+k) s a -> MVector v n s a
@@ -164,16 +164,16 @@
   where i = fromInteger (natVal (Proxy :: Proxy n))
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall v n k s a p. (KnownNat n, VGM.MVector v a)
       => p n -> MVector v (n+k) s a -> MVector v n s a
 take' _ = take
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall v n k s a. (KnownNat n, VGM.MVector v a)
      => MVector v (n+k) s a -> MVector v k s a
@@ -181,16 +181,16 @@
   where i = fromInteger (natVal (Proxy :: Proxy n))
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- givel explicitly as a 'Proxy' argument.
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- given explicitly as a 'Proxy' argument.
 drop' :: forall v n k s a p. (KnownNat n, VGM.MVector v a)
       => p n -> MVector v (n+k) s a -> MVector v k s a
 drop' _ = drop
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall v n m s a. (KnownNat n, VGM.MVector v a)
         => MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)
 splitAt (MVector v) = (MVector a, MVector b)
@@ -198,8 +198,8 @@
         (a, b) = VGM.splitAt i v
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying. The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall v n m s a p. (KnownNat n, VGM.MVector v a)
          => p n -> MVector v (n+m) s a -> (MVector v n s a, MVector v m s a)
@@ -208,9 +208,7 @@
 
 -- ** Overlaps
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- inferred from the type.
+-- | /O(1)/ Check whether two vectors overlap. 
 overlaps :: forall v n k s a. VGM.MVector v a
          => MVector v n s a
          -> MVector v k s a
@@ -354,13 +352,13 @@
 unsafeModify (MVector v) = VGM.unsafeModify v
 {-# inline unsafeModify #-}
 
--- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.
+-- | /O(1)/ Swap the elements at given type-safe positions using 'Finite's.
 swap :: forall v n m a. (PrimMonad m, VGM.MVector v a)
      => MVector v n (PrimState m) a -> Finite n -> Finite n -> m ()
 swap (MVector v) (Finite i) (Finite j) = VGM.unsafeSwap v (fromIntegral i) (fromIntegral j)
 {-# inline swap #-}
 
--- | /O(1)/ Swap the elements at a given 'Int' position without bounds
+-- | /O(1)/ Swap the elements at given 'Int' positions without bounds
 -- checking.
 unsafeSwap :: forall v n m a. (PrimMonad m, VGM.MVector v a)
            => MVector v n (PrimState m) a -> Int -> Int -> m ()
@@ -391,7 +389,7 @@
 #if MIN_VERSION_vector(0,12,0)
 -- * Modifying vectors
 
--- | Compute the next (lexicographically) permutation of a given vector
+-- | Compute the next permutation (in lexicographic order) of a given vector
 -- in-place.  Returns 'False' when the input is the last permutation.
 nextPermutation :: forall v n e m. (Ord e, PrimMonad m, VGM.MVector v e)
                 => MVector v n (PrimState m) e -> m Bool
diff --git a/src/Data/Vector/Generic/Mutable/Sized/Internal.hs b/src/Data/Vector/Generic/Mutable/Sized/Internal.hs
--- a/src/Data/Vector/Generic/Mutable/Sized/Internal.hs
+++ b/src/Data/Vector/Generic/Mutable/Sized/Internal.hs
@@ -7,13 +7,14 @@
 
 module Data.Vector.Generic.Mutable.Sized.Internal
   ( MVector(..)
-  ) where
+  )
+where
 
-import GHC.Generics (Generic)
-import GHC.TypeLits
-import Control.DeepSeq (NFData)
-import Data.Data
-import Foreign.Storable
+import           GHC.Generics                   ( Generic )
+import           GHC.TypeLits
+import           Control.DeepSeq                ( NFData )
+import           Data.Data
+import           Foreign.Storable
 
 -- | A wrapper to tag mutable vectors with a type level length.
 --
diff --git a/src/Data/Vector/Generic/Sized.hs b/src/Data/Vector/Generic/Sized.hs
--- a/src/Data/Vector/Generic/Sized.hs
+++ b/src/Data/Vector/Generic/Sized.hs
@@ -1,23 +1,25 @@
 {-# LANGUAGE DataKinds #-}
-{-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE DeriveGeneric #-}
 {-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE ExistentialQuantification #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# LANGUAGE KindSignatures #-}
 {-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeOperators #-}
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE TypeFamilies #-}
 {-# LANGUAGE TypeApplications #-}
+{-# LANGUAGE PatternSynonyms #-}
+{-# LANGUAGE ViewPatterns #-}
 {-# LANGUAGE CPP #-}
 
 #if MIN_VERSION_base(4,12,0)
 {-# LANGUAGE NoStarIsType #-}
 #endif
 
+{-# OPTIONS_GHC -Wno-orphans #-}
 {-|
 This module reexports the functionality in 'Data.Vector.Generic' which maps well
 to explicity sized vectors.
@@ -30,7 +32,7 @@
 -}
 
 module Data.Vector.Generic.Sized
-  ( Vector
+  ( Vector(SomeSized)
   , MVector
    -- * Accessors
    -- ** Length information
@@ -248,26 +250,24 @@
 import Data.Vector.Generic.Sized.Internal
 import qualified Data.Vector.Generic as VG
 import qualified Data.Vector as Boxed
+import qualified Data.Vector.Storable as Storable
+import qualified Data.Vector.Unboxed as Unboxed
 import qualified Data.Vector.Generic.Mutable.Sized as SVGM
 import Data.Vector.Generic.Mutable.Sized.Internal
-import GHC.Generics (Generic)
 import GHC.TypeLits
 import Data.Bifunctor
 import Data.Finite
 import Data.Finite.Internal
 import Data.Proxy
-import Control.DeepSeq (NFData)
 import Control.Monad.Primitive
 import Foreign.Storable
 import Data.Data
-import Data.Functor.Classes
 import Control.Comonad
 import Foreign.Ptr (castPtr)
 import Data.Semigroup
 import Text.Read.Lex
 import Text.ParserCombinators.ReadPrec
 import GHC.Read
-import Data.Type.Equality
 import Unsafe.Coerce
 import qualified Data.Functor.Rep as Rep
 import Data.Distributive
@@ -280,17 +280,19 @@
 
 
 import Data.IndexedListLiterals hiding (toList, fromList)
+import Data.Hashable (Hashable(..))
 import qualified Data.IndexedListLiterals as ILL
+import Data.Vector.Unboxed (Unbox)
 
 instance (KnownNat n, VG.Vector v a, Read (v a)) => Read (Vector v n a) where
   readPrec = parens $ prec 10 $ do
       expectP (Ident "Vector")
       vec <- readPrec
-      if VG.length vec == (fromIntegral $ natVal (Proxy :: Proxy n)) then return $ Vector vec else pfail
+      if VG.length vec == fromIntegral (natVal (Proxy @n)) then return $ Vector vec else pfail
 
 type instance VG.Mutable (Vector v n) = MVector (VG.Mutable v) n
 
--- | Any sized vector containing storable elements is itself storable.
+-- | Any sized vector containing 'Storable' elements is itself 'Storable'.
 instance (KnownNat n, Storable a, VG.Vector v a)
       => Storable (Vector v n a) where
   sizeOf _ = sizeOf (undefined :: a) * fromIntegral (natVal (Proxy :: Proxy n))
@@ -331,10 +333,10 @@
 -- @
 instance (KnownNat n, n ~ (1 + m)) => Comonad (Vector Boxed.Vector n) where
   extract = head
-  extend f r@(Vector v) = Vector $ VG.generate len (\i -> f (Vector (VG.slice i len v')))
+  extend f r@(Vector v) = Vector $ VG.generate l (\i -> f (Vector (VG.slice i l v')))
     where
       v' = v VG.++ VG.init v
-      len = length r
+      l = length r
 
 instance (KnownNat n, n ~ (1 + m)) => ComonadApply (Vector Boxed.Vector n) where
   (<@>) = (<*>)
@@ -359,7 +361,11 @@
 -- 'Monoid' will dodge the 'KnownNat' constraint.
 instance (Monoid m, VG.Vector v m, KnownNat n) => Monoid (Vector v n m) where
   mempty = replicate mempty
+#if MIN_VERSION_base(4,11,0)
+  -- begone, non-canonical mappend!
+#else
   mappend = zipWith mappend
+#endif
   mconcat vs = generate $ mconcat . flip fmap vs . flip index
 
 instance KnownNat n => Distributive (Vector Boxed.Vector n) where
@@ -373,6 +379,18 @@
   index = Data.Vector.Generic.Sized.index
   {-# inline index #-}
 
+instance (Eq a, Hashable a) => Hashable (Vector Boxed.Vector n a) where
+  {-# INLINE hashWithSalt #-}
+  hashWithSalt salt = hashWithSalt salt . toList
+
+instance (Eq a, Hashable a, Storable a) => Hashable (Vector Storable.Vector n a) where
+  {-# INLINE hashWithSalt #-}
+  hashWithSalt salt = hashWithSalt salt . toList
+
+instance (Eq a, Hashable a, Unbox a) => Hashable (Vector Unboxed.Vector n a) where
+  {-# INLINE hashWithSalt #-}
+  hashWithSalt salt = hashWithSalt salt . toList
+
 -- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
 -- 'natVal' than 'Data.Vector.length', extracting the value from the 'KnownNat'
 -- instance and not looking at the vector itself.
@@ -420,7 +438,7 @@
   where i = fromIntegral (natVal p)
 {-# inline index' #-}
 
--- | /O(1)/ Indexing using an Int without bounds checking.
+-- | /O(1)/ Indexing using an 'Int' without bounds checking.
 unsafeIndex :: forall v n a. VG.Vector v a
       => Vector v n a -> Int -> a
 unsafeIndex (Vector v) i = v `VG.unsafeIndex` i
@@ -453,18 +471,38 @@
 -- | Lens to access (/O(1)/) and update (/O(n)/) the last element of a non-empty vector.
 _last :: forall v n a f. (VG.Vector v a, Functor f)
        => (a -> f a) -> Vector v (n+1) a -> f (Vector v (n+1) a)
-_last f vector = (\x -> snoc (init vector) x) <$> f (last vector)
+_last f vector = snoc (init vector) <$> f (last vector)
 {-# inline _last #-}
 
--- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
--- an explanation of why this is useful.
+-- | /O(1)/ Safe indexing in a monad. 
+--
+-- The monad allows operations to be strict in the vector when necessary.
+-- Suppose vector copying is implemented like this:
+--
+-- @
+-- copy mv v = ... write mv i (v ! i) ...
+-- @
+--
+-- For lazy vectors, @v ! i@ would not be evaluated, which means that @mv@ would
+-- unnecessarily retain a reference to @v@ in each element when written.
+--
+-- With 'indexM', copying can be implemented like this instead:
+--
+-- @
+-- copy mv v = ... do
+--                  x <- indexM v i
+--                  write mv i x
+-- @
+--
+-- Here, no references to @v@ are retained, because indexing (but /not/ the
+-- elements) are evaluated eagerly.
 indexM :: forall v n a m. (VG.Vector v a, Monad m)
       => Vector v n a -> Finite n -> m a
 indexM (Vector v) (Finite i) = v `VG.indexM` fromIntegral i
 {-# inline indexM #-}
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
--- 'VG.indexM' for an explanation of why this is useful.
+-- 'indexM' for an explanation of why this is useful.
 indexM' :: forall v n k a m p. (KnownNat n, VG.Vector v a, Monad m)
       => Vector v (n+k) a -> p n -> m a
 indexM' (Vector v) p = v `VG.indexM` i
@@ -472,21 +510,21 @@
 {-# inline indexM' #-}
 
 -- | /O(1)/ Indexing using an Int without bounds checking. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'indexM' for an explanation of why this is useful.
 unsafeIndexM :: forall v n a m. (VG.Vector v a, Monad m)
       => Vector v n a -> Int -> m a
 unsafeIndexM (Vector v) i = v `VG.unsafeIndexM` i
 {-# inline unsafeIndexM #-}
 
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'indexM' for an explanation of why this is useful.
 headM :: forall v n a m. (VG.Vector v a, Monad m)
       => Vector v (1+n) a -> m a
 headM (Vector v) = VG.unsafeHeadM v
 {-# inline headM #-}
 
 -- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'indexM' for an explanation of why this is useful.
 lastM :: forall v n a m. (VG.Vector v a, Monad m)
       => Vector v (n+1) a -> m a
 lastM (Vector v) = VG.unsafeLastM v
@@ -528,8 +566,8 @@
 tail (Vector v) = Vector (VG.unsafeTail v)
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall v n m a. (KnownNat n, VG.Vector v a)
      => Vector v (n+m) a -> Vector v n a
@@ -537,16 +575,16 @@
   where i = fromIntegral (natVal (Proxy :: Proxy n))
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall v n m a p. (KnownNat n, VG.Vector v a)
       => p n -> Vector v (n+m) a -> Vector v n a
 take' _ = take
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall v n m a. (KnownNat n, VG.Vector v a)
      => Vector v (n+m) a -> Vector v m a
@@ -554,16 +592,16 @@
   where i = fromIntegral (natVal (Proxy :: Proxy n))
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall v n m a p. (KnownNat n, VG.Vector v a)
       => p n -> Vector v (n+m) a -> Vector v m a
 drop' _ = drop
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall v n m a. (KnownNat n, VG.Vector v a)
         => Vector v (n+m) a -> (Vector v n a, Vector v m a)
 splitAt (Vector v) = (Vector a, Vector b)
@@ -571,8 +609,8 @@
         (a, b) = VG.splitAt i v
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall v n m a p. (KnownNat n, VG.Vector v a)
          => p n -> Vector v (n+m) a -> (Vector v n a, Vector v m a)
@@ -599,9 +637,11 @@
 singleton a = Vector (VG.singleton a)
 {-# inline singleton #-}
 
--- | /O(n)/ Construct a vector in a type safe manner
+-- | /O(n)/ Construct a vector in a type-safe manner.
+-- @
 --   fromTuple (1,2) :: Vector v 2 Int
 --   fromTuple ("hey", "what's", "going", "on") :: Vector v 4 String
+-- @
 fromTuple :: forall v a input length.
              (VG.Vector v a, IndexedListLiterals input length a, KnownNat length)
           => input -> Vector v length a
@@ -622,7 +662,7 @@
 replicate' _ = replicate
 {-# inline replicate' #-}
 
--- | /O(n)/ construct a vector of the given length by applying the function to
+-- | /O(n)/ Construct a vector of the given length by applying the function to
 -- each index where the length is inferred from the type.
 generate :: forall v n a. (KnownNat n, VG.Vector v a)
          => (Finite n -> a) -> Vector v n a
@@ -630,14 +670,14 @@
   where i = fromIntegral (natVal (Proxy :: Proxy n))
 {-# inline generate #-}
 
--- | /O(n)/ construct a vector of the given length by applying the function to
+-- | /O(n)/ Construct a vector of the given length by applying the function to
 -- each index where the length is given explicitly as a 'Proxy' argument.
 generate' :: forall v n a p. (KnownNat n, VG.Vector v a)
           => p n -> (Finite n -> a) -> Vector v n a
 generate' _ = generate
 {-# inline generate' #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is the original value.
 -- The length is inferred from the type.
 iterateN :: forall v n a. (KnownNat n, VG.Vector v a)
          => (a -> a) -> a -> Vector v n a
@@ -645,7 +685,7 @@
   where i = fromIntegral (natVal (Proxy :: Proxy n))
 {-# inline iterateN #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is the original value.
 -- The length is given explicitly as a 'Proxy' argument.
 iterateN' :: forall v n a p. (KnownNat n, VG.Vector v a)
           => p n -> (a -> a) -> a -> Vector v n a
@@ -672,7 +712,7 @@
 {-# inline replicateM' #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is inferred from the type.
+-- each index where @n@ is inferred from the type.
 generateM :: forall v n m a. (KnownNat n, VG.Vector v a, Monad m)
           => (Finite n -> m a) -> m (Vector v n a)
 generateM f = Vector <$> VG.generateM i (f . Finite . fromIntegral)
@@ -680,7 +720,7 @@
 {-# inline generateM #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is given explicitly as a 'Proxy' argument.
+-- each index where @n@ is given explicitly as a 'Proxy' argument.
 generateM' :: forall v n m a p. (KnownNat n, VG.Vector v a, Monad m)
            => p n -> (Finite n -> m a) -> m (Vector v n a)
 generateM' _ = generateM
@@ -691,7 +731,7 @@
 --
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is inferred from the
+-- the generator function to the a seed. The length is inferred from the
 -- type.
 unfoldrN :: forall v n a b. (KnownNat n, VG.Vector v a)
          => (b -> (a, b)) -> b -> Vector v n a
@@ -700,7 +740,7 @@
 {-# inline unfoldrN #-}
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is given explicitly
+-- the generator function to the a seed. The length is given explicitly
 -- as a 'Proxy' argument.
 unfoldrN' :: forall v n a b p. (KnownNat n, VG.Vector v a)
           => p n -> (b -> (a, b)) -> b -> Vector v n a
@@ -711,23 +751,23 @@
 -- ** Enumeration
 --
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is inferred from the type.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@,
+-- ... @x + (n - 1)@. The length is inferred from the type.
 enumFromN :: forall v n a. (KnownNat n, VG.Vector v a, Num a)
           => a -> Vector v n a
 enumFromN a = Vector (VG.enumFromN a i)
   where i = fromIntegral (natVal (Proxy :: Proxy n))
 {-# inline enumFromN #-}
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@,
+-- ..., @x + (n - 1)@ The length is given explicitly as a 'Proxy' argument.
 enumFromN' :: forall v n a p. (KnownNat n, VG.Vector v a, Num a)
            => a -> p n -> Vector v n a
 enumFromN' a _ = enumFromN a
 {-# inline enumFromN' #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is inferred from the type.
+-- @x+2y@, ... @x + (n - 1)y@. The length is inferred from the type.
 enumFromStepN :: forall v n a. (KnownNat n, VG.Vector v a, Num a)
           => a -> a -> Vector v n a
 enumFromStepN a a' = Vector (VG.enumFromStepN a a' i)
@@ -735,7 +775,7 @@
 {-# inline enumFromStepN #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- @x+2y@, ..., @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.
 enumFromStepN' :: forall v n a p. (KnownNat n, VG.Vector v a, Num a)
                => a -> a -> p n -> Vector v n a
 enumFromStepN' a a' _ = enumFromStepN a a'
@@ -975,7 +1015,7 @@
 -- ** Indexing
 --
 
--- | /O(n)/ Pair each element in a vector with its index
+-- | /O(n)/ Pair each element in a vector with its index.
 indexed :: (VG.Vector v a, VG.Vector v (Int, a), VG.Vector v (Finite n,a))
         => Vector v n a -> Vector v n (Finite n,a)
 indexed (Vector v) = Vector ((VG.map . first) (Finite . fromIntegral) $ VG.indexed v)
@@ -985,51 +1025,51 @@
 -- ** Mapping
 --
 
--- | /O(n)/ Map a function over a vector
+-- | /O(n)/ Map a function over a vector.
 map :: (VG.Vector v a, VG.Vector v b)
     => (a -> b) -> Vector v n a -> Vector v n b
 map f (Vector v) = Vector (VG.map f v)
 {-# inline map #-}
 
--- | /O(n)/ Apply a function to every element of a vector and its index
+-- | /O(n)/ Apply a function to every element of a vector and its index.
 imap :: (VG.Vector v a, VG.Vector v b)
      => (Finite n -> a -> b) -> Vector v n a -> Vector v n b
 imap f (Vector v) = Vector (VG.imap (f . Finite . fromIntegral) v)
 {-# inline imap #-}
 
 -- | /O(n*m)/ Map a function over a vector and concatenate the results. The
--- function is required to always return the same length vector.
-concatMap :: (VG.Vector v a, VG.Vector v b)
-          => (a -> Vector v m b) -> Vector v n a -> Vector v (n*m) b
-concatMap f (Vector v) = Vector (VG.concatMap (fromSized . f) v)
-{-# inline concatMap #-}
+-- function is required to always return a vector of the same length.
+concatMap :: (VG.Vector v a, VG.Vector v' b) 
+          => (a -> Vector v' m b) -> Vector v n a -> Vector v' (n*m) b
+concatMap f (Vector v) = Vector . VG.concat . fmap (fromSized . f) . VG.toList $ v
+{-# inline concatMap #-}  
 
 --
 -- ** Monadic mapping
 --
 
 -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
--- vector of results
+-- vector of results.
 mapM :: (Monad m, VG.Vector v a, VG.Vector v b)
       => (a -> m b) -> Vector v n a -> m (Vector v n b)
 mapM f (Vector v) = Vector <$> VG.mapM f v
 {-# inline mapM #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, yielding a vector of results
+-- index, yielding a vector of results.
 imapM :: (Monad m, VG.Vector v a, VG.Vector v b)
       => (Finite n -> a -> m b) -> Vector v n a -> m (Vector v n b)
-imapM f (Vector v) = Vector <$> (VG.imapM (f . Finite . fromIntegral) v)
+imapM f (Vector v) = Vector <$> VG.imapM (f . Finite . fromIntegral) v
 {-# inline imapM #-}
 
 -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
--- results
+-- results.
 mapM_ :: (Monad m, VG.Vector v a) => (a -> m b) -> Vector v n a -> m ()
 mapM_ f (Vector v) = VG.mapM_ f v
 {-# inline mapM_ #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, ignoring the results
+-- index, ignoring the results.
 imapM_ :: (Monad m, VG.Vector v a) => (Finite n -> a -> m b) -> Vector v n a -> m ()
 imapM_ f (Vector v) = VG.imapM_ (f . Finite . fromIntegral) v
 {-# inline imapM_ #-}
@@ -1202,27 +1242,27 @@
 --
 
 -- | /O(n)/ Zip the two vectors of the same length with the monadic action and
--- yield a vector of results
+-- yield a vector of results.
 zipWithM :: (Monad m, VG.Vector v a, VG.Vector v b, VG.Vector v c)
          => (a -> b -> m c) -> Vector v n a -> Vector v n b -> m (Vector v n c)
 zipWithM f (Vector as) (Vector bs) = Vector <$> VG.zipWithM f as bs
 {-# inline zipWithM #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes the
--- element index and yield a vector of results
+-- element index and yield a vector of results.
 izipWithM :: (Monad m, VG.Vector v a, VG.Vector v b, VG.Vector v c)
          => (Finite n -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m (Vector v n c)
 izipWithM m (Vector as) (Vector bs) = Vector <$> VG.izipWithM (m . Finite . fromIntegral) as bs
 {-# inline izipWithM #-}
 
--- | /O(n)/ Zip the two vectors with the monadic action and ignore the results
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.
 zipWithM_ :: (Monad m, VG.Vector v a, VG.Vector v b)
           => (a -> b -> m c) -> Vector v n a -> Vector v n b -> m ()
 zipWithM_ f (Vector as) (Vector bs) = VG.zipWithM_ f as bs
 {-# inline zipWithM_ #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes
--- the element index and ignore the results
+-- the element index and ignore the results.
 izipWithM_ :: (Monad m, VG.Vector v a, VG.Vector v b)
            => (Finite n -> a -> b -> m c) -> Vector v n a -> Vector v n b -> m ()
 izipWithM_ m (Vector as) (Vector bs) = VG.izipWithM_ (m . Finite . fromIntegral) as bs
@@ -1284,13 +1324,13 @@
 
 
 infix 4 `elem`
--- | /O(n)/ Check if the vector contains an element
+-- | /O(n)/ Check if the vector contains an element.
 elem :: (VG.Vector v a, Eq a) => a -> Vector v n a -> Bool
 elem x (Vector v) = VG.elem x v
 {-# inline elem #-}
 
 infix 4 `notElem`
--- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').
 notElem :: (VG.Vector v a, Eq a) => a -> Vector v n a -> Bool
 notElem x (Vector v) = VG.notElem x v
 {-# inline notElem #-}
@@ -1318,64 +1358,64 @@
 -- * Folding
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Left fold
+-- | /O(n)/ Left fold.
 foldl :: VG.Vector v b => (a -> b -> a) -> a -> Vector v n b -> a
 foldl f z = VG.foldl f z . fromSized
 {-# inline foldl #-}
 
--- | /O(n)/ Left fold on non-empty vectors
+-- | /O(n)/ Left fold on non-empty vectors.
 foldl1 :: VG.Vector v a => (a -> a -> a) -> Vector v (1+n) a -> a
 foldl1 f = VG.foldl1 f . fromSized
 {-# inline foldl1 #-}
 
--- | /O(n)/ Left fold with strict accumulator
+-- | /O(n)/ Left fold with strict accumulator.
 foldl' :: VG.Vector v b => (a -> b -> a) -> a -> Vector v n b -> a
 foldl' f z = VG.foldl' f z . fromSized
 {-# inline foldl' #-}
 
--- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.
 foldl1' :: VG.Vector v a => (a -> a -> a) -> Vector v (1+n) a -> a
 foldl1' f = VG.foldl1' f . fromSized
 {-# inline foldl1' #-}
 
--- | /O(n)/ Right fold
+-- | /O(n)/ Right fold.
 foldr :: VG.Vector v a => (a -> b -> b) -> b -> Vector v n a -> b
 foldr f z = VG.foldr f z . fromSized
 {-# inline foldr #-}
 
--- | /O(n)/ Right fold on non-empty vectors
+-- | /O(n)/ Right fold on non-empty vectors.
 foldr1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> a
 foldr1 f = VG.foldr1 f . fromSized
 {-# inline foldr1 #-}
 
--- | /O(n)/ Right fold with a strict accumulator
+-- | /O(n)/ Right fold with a strict accumulator.
 foldr' :: VG.Vector v a => (a -> b -> b) -> b -> Vector v n a -> b
 foldr' f z = VG.foldr' f z . fromSized
 {-# inline foldr' #-}
 
--- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.
 foldr1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> a
 foldr1' f = VG.foldr1' f . fromSized
 {-# inline foldr1' #-}
 
--- | /O(n)/ Left fold (function applied to each element and its index)
+-- | /O(n)/ Left fold (function applied to each element and its index).
 ifoldl :: VG.Vector v b => (a -> Finite n -> b -> a) -> a -> Vector v n b -> a
 ifoldl f z = VG.ifoldl (\x -> f x . Finite . fromIntegral) z . fromSized
 {-# inline ifoldl #-}
 
 -- | /O(n)/ Left fold with strict accumulator (function applied to each element
--- and its index)
+-- and its index).
 ifoldl' :: VG.Vector v b => (a -> Finite n -> b -> a) -> a -> Vector v n b -> a
 ifoldl' f z = VG.ifoldl' (\x -> f x . Finite . fromIntegral) z . fromSized
 {-# inline ifoldl' #-}
 
--- | /O(n)/ Right fold (function applied to each element and its index)
+-- | /O(n)/ Right fold (function applied to each element and its index).
 ifoldr :: VG.Vector v a => (Finite n -> a -> b -> b) -> b -> Vector v n a -> b
 ifoldr f z = VG.ifoldr (f . Finite . fromIntegral) z . fromSized
 {-# inline ifoldr #-}
 
 -- | /O(n)/ Right fold with strict accumulator (function applied to each
--- element and its index)
+-- element and its index).
 ifoldr' :: VG.Vector v a => (Finite n -> a -> b -> b) -> b -> Vector v n a -> b
 ifoldr' f z = VG.ifoldr' (f . Finite . fromIntegral) z . fromSized
 {-# inline ifoldr' #-}
@@ -1402,12 +1442,12 @@
 or = VG.or . fromSized
 {-# inline or #-}
 
--- | /O(n)/ Compute the sum of the elements
+-- | /O(n)/ Compute the sum of the elements.
 sum :: (VG.Vector v a, Num a) => Vector v n a -> a
 sum = VG.sum . fromSized
 {-# inline sum #-}
 
--- | /O(n)/ Compute the produce of the elements
+-- | /O(n)/ Compute the product of the elements.
 product :: (VG.Vector v a, Num a) => Vector v n a -> a
 product = VG.product . fromSized
 {-# inline product #-}
@@ -1462,74 +1502,74 @@
 
 -- ** Monadic folds
 
--- | /O(n)/ Monadic fold
+-- | /O(n)/ Monadic fold.
 foldM :: (Monad m, VG.Vector v b) => (a -> b -> m a) -> a -> Vector v n b -> m a
 foldM m z = VG.foldM m z . fromSized
 {-# inline foldM #-}
 
--- | /O(n)/ Monadic fold (action applied to each element and its index)
+-- | /O(n)/ Monadic fold (action applied to each element and its index).
 ifoldM :: (Monad m, VG.Vector v b) => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m a
 ifoldM m z = VG.ifoldM (\x -> m x . Finite . fromIntegral) z . fromSized
 {-# inline ifoldM #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors
+-- | /O(n)/ Monadic fold over non-empty vectors.
 fold1M :: (Monad m, VG.Vector v a)
        => (a -> a -> m a) -> Vector v (1+n) a -> m a
 fold1M m = VG.fold1M m . fromSized
 {-# inline fold1M #-}
 
--- | /O(n)/ Monadic fold with strict accumulator
+-- | /O(n)/ Monadic fold with strict accumulator.
 foldM' :: (Monad m, VG.Vector v b) => (a -> b -> m a) -> a -> Vector v n b -> m a
 foldM' m z = VG.foldM' m z . fromSized
 {-# inline foldM' #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator (action applied to each
--- element and its index)
+-- element and its index).
 ifoldM' :: (Monad m, VG.Vector v b)
         => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m a
 ifoldM' m z = VG.ifoldM' (\x -> m x . Finite . fromIntegral) z . fromSized
 {-# inline ifoldM' #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.
 fold1M' :: (Monad m, VG.Vector v a)
         => (a -> a -> m a) -> Vector v (n+1) a -> m a
 fold1M' m = VG.fold1M' m . fromSized
 {-# inline fold1M' #-}
 
--- | /O(n)/ Monadic fold that discards the result
+-- | /O(n)/ Monadic fold that discards the result.
 foldM_ :: (Monad m, VG.Vector v b)
        => (a -> b -> m a) -> a -> Vector v n b -> m ()
 foldM_ m z = VG.foldM_ m z . fromSized
 {-# inline foldM_ #-}
 
 -- | /O(n)/ Monadic fold that discards the result (action applied to
--- each element and its index)
+-- each element and its index).
 ifoldM_ :: (Monad m, VG.Vector v b)
         => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m ()
 ifoldM_ m z = VG.ifoldM_ (\x -> m x . Finite . fromIntegral)  z . fromSized
 {-# inline ifoldM_ #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.
 fold1M_ :: (Monad m, VG.Vector v a)
         => (a -> a -> m a) -> Vector v (n+1) a -> m ()
 fold1M_ m = VG.fold1M_ m . fromSized
 {-# inline fold1M_ #-}
 
--- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result.
 foldM'_ :: (Monad m, VG.Vector v b)
         => (a -> b -> m a) -> a -> Vector v n b -> m ()
 foldM'_ m z = VG.foldM'_ m z . fromSized
 {-# inline foldM'_ #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator that discards the result
--- (action applied to each element and its index)
+-- (action applied to each element and its index).
 ifoldM'_ :: (Monad m, VG.Vector v b)
          => (a -> Finite n -> b -> m a) -> a -> Vector v n b -> m ()
 ifoldM'_ m z = VG.ifoldM'_ (\x -> m x . Finite . fromIntegral) z . fromSized
 {-# inline ifoldM'_ #-}
 
 -- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
--- that discards the result
+-- that discards the result.
 fold1M'_ :: (Monad m, VG.Vector v a)
          => (a -> a -> m a) -> Vector v (n+1) a -> m ()
 fold1M'_ m = VG.fold1M'_ m . fromSized
@@ -1537,13 +1577,13 @@
 
 -- ** Monadic sequencing
 
--- | Evaluate each action and collect the results
+-- | Evaluate each action and collect the results.
 sequence :: (Monad m, VG.Vector v a, VG.Vector v (m a))
          => Vector v n (m a) -> m (Vector v n a)
 sequence (Vector v) = Vector <$> VG.sequence v
 {-# inline sequence #-}
 
--- | Evaluate each action and discard the results
+-- | Evaluate each action and discard the results.
 sequence_ :: (Monad m, VG.Vector v (m a)) => Vector v n (m a) -> m ()
 sequence_ (Vector v) = VG.sequence_ v
 {-# inline sequence_ #-}
@@ -1564,7 +1604,7 @@
 prescanl f z = withVectorUnsafe (VG.prescanl f z )
 {-# inline prescanl #-}
 
--- | /O(n)/ Prescan with strict accumulator
+-- | /O(n)/ Prescan with strict accumulator.
 prescanl' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a
 prescanl' f z = withVectorUnsafe (VG.prescanl' f z )
 {-# inline prescanl' #-}
@@ -1574,68 +1614,68 @@
 postscanl f z = withVectorUnsafe (VG.postscanl f z )
 {-# inline postscanl #-}
 
--- | /O(n)/ Scan with strict accumulator
+-- | /O(n)/ Scan with strict accumulator.
 postscanl' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a
 postscanl' f z = withVectorUnsafe (VG.postscanl' f z )
 {-# inline postscanl' #-}
 
--- | /O(n)/ Haskell-style scan
+-- | /O(n)/ Haskell-style scan.
 scanl :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a
 scanl f z = withVectorUnsafe (VG.scanl f z )
 {-# inline scanl #-}
 
--- | /O(n)/ Haskell-style scan with strict accumulator
+-- | /O(n)/ Haskell-style scan with strict accumulator.
 scanl' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> a) -> a -> Vector v n b -> Vector v n a
 scanl' f z = withVectorUnsafe (VG.scanl' f z )
 {-# inline scanl' #-}
 
--- | /O(n)/ Scan over a non-empty vector
+-- | /O(n)/ Scan over a non-empty vector.
 scanl1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a
 scanl1 f = withVectorUnsafe (VG.scanl1 f )
 {-# inline scanl1 #-}
 
--- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.
 scanl1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a
 scanl1' f = withVectorUnsafe (VG.scanl1' f )
 {-# inline scanl1' #-}
 
--- | /O(n)/ Right-to-left prescan
+-- | /O(n)/ Right-to-left prescan.
 prescanr :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 prescanr f z = withVectorUnsafe (VG.prescanr f z )
 {-# inline prescanr #-}
 
--- | /O(n)/ Right-to-left prescan with strict accumulator
+-- | /O(n)/ Right-to-left prescan with strict accumulator.
 prescanr' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 prescanr' f z = withVectorUnsafe (VG.prescanr' f z )
 {-# inline prescanr' #-}
 
--- | /O(n)/ Right-to-left scan
+-- | /O(n)/ Right-to-left scan.
 postscanr :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 postscanr f z = withVectorUnsafe (VG.postscanr f z )
 {-# inline postscanr #-}
 
--- | /O(n)/ Right-to-left scan with strict accumulator
+-- | /O(n)/ Right-to-left scan with strict accumulator.
 postscanr' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 postscanr' f z = withVectorUnsafe (VG.postscanr' f z )
 {-# inline postscanr' #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan
+-- | /O(n)/ Right-to-left Haskell-style scan.
 scanr :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 scanr f z = withVectorUnsafe (VG.scanr f z )
 {-# inline scanr #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.
 scanr' :: (VG.Vector v a, VG.Vector v b) => (a -> b -> b) -> b -> Vector v n a -> Vector v n b
 scanr' f z = withVectorUnsafe (VG.scanr' f z )
 {-# inline scanr' #-}
 
--- | /O(n)/ Right-to-left scan over a non-empty vector
+-- | /O(n)/ Right-to-left scan over a non-empty vector.
 scanr1 :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a
 scanr1 f = withVectorUnsafe (VG.scanr1 f )
 {-# inline scanr1 #-}
 
 -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
--- accumulator
+-- accumulator.
 scanr1' :: VG.Vector v a => (a -> a -> a) -> Vector v (n+1) a -> Vector v (n+1) a
 scanr1' f = withVectorUnsafe (VG.scanr1' f )
 {-# inline scanr1' #-}
@@ -1645,12 +1685,12 @@
 
 -- ** Lists
 
--- | /O(n)/ Convert a vector to a list
+-- | /O(n)/ Convert a vector to a list.
 toList :: VG.Vector v a => Vector v n a -> [a]
 toList = VG.toList . fromSized
 {-# inline toList #-}
 
--- | /O(n)/ Convert a list to a vector
+-- | /O(n)/ Convert a list to a vector.
 fromList :: (VG.Vector v a, KnownNat n) => [a] -> Maybe (Vector v n a)
 fromList = toSized . VG.fromList
 {-# inline fromList #-}
@@ -1683,7 +1723,7 @@
 
 -- ** Different Vector types
 
--- | /O(n)/ Convert different vector types
+-- | /O(n)/ Convert different vector types.
 convert :: (VG.Vector v a, VG.Vector w a) => Vector v n a -> Vector w n a
 convert = withVectorUnsafe VG.convert
 {-# inline convert #-}
@@ -1759,6 +1799,101 @@
 withVectorUnsafe :: (v a -> w b) -> Vector v n a -> Vector w n b
 withVectorUnsafe f (Vector v) = Vector (f v)
 {-# inline withVectorUnsafe #-}
+
+-- | Internal existential wrapper used for implementing 'SomeSized'
+-- pattern synonym
+data SV_ v a = forall n. KnownNat n => SV_ (Vector v n a)
+
+-- | Pattern synonym that lets you treat an unsized vector as if it
+-- "contained" a sized vector.  If you pattern match on an unsized vector,
+-- its contents will be the /sized/ vector counterpart.
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc ('SomeSized' v) =
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+--         -- ^ here, v is `Sized.Vector n Int`, and we have
+--                     `'KnownNat' n`
+-- @
+--
+-- The @n@ type variable will be properly instantiated to whatever the
+-- length of the vector is, and you will also have a @'KnownNat' n@
+-- instance available.  You can get @n@ in scope by turning on
+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector
+-- n Int)@.
+--
+-- Without this, you would otherwise have to use 'withSized' to do the same
+-- thing:
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc u = 'withSized' u $ \\v ->
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+-- @
+--
+-- Remember that the type of final result of your function (the @Int@,
+-- here) must /not/ depend on @n@.  However, the types of the intermediate
+-- values are allowed to depend on @n@.
+--
+-- This is /especially/ useful in do blocks, where you can pattern match on
+-- the unsized results of actions, to use the sized vector in the rest of
+-- the do block.  You also get a @'KnownNat' n@ constraint for the
+-- remainder of the do block.
+--
+-- @
+-- -- If you had:
+-- getAVector :: IO (Unsized.Vector Int)
+--
+-- main :: IO ()
+-- main = do
+--     SomeSized v <- getAVector -- v is `Sized.Vector n Int`
+--     print v
+--
+--     -- alternatively, get n in scope
+--     SomeSized (v2 :: Sized.Vector n Int) <- getAVector
+--     print v2
+-- @
+--
+-- Remember that the final type of the result of the do block ('()', here)
+-- must not depend on @n@.  However, the 
+--
+-- Also useful in ghci, where you can pattern match to get sized vectors
+-- from unsized vectors.
+--
+-- @
+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)
+--              -- ^ v is `Sized.Vector n Int`
+-- @
+--
+-- This enables interactive exploration with sized vectors in ghci, and is
+-- useful for using with other libraries and functions that expect sized
+-- vectors in an interactive setting.
+--
+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci
+-- session using ScopedTypeVariables, like you can with do blocks)
+--
+-- You can also use this as a constructor, to take a sized vector and
+-- "hide" the size, to produce an unsized vector:
+--
+-- @
+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a
+-- @
+--
+-- Note that due to quirks in GHC pattern synonym completeness checking,
+-- you will get incomplete pattern matches if you use this polymorphically
+-- over different vector types, or you use any vector type other than the
+-- three supported by this library (normal, storable, unboxed).
+pattern SomeSized
+    :: VG.Vector v a
+    => forall n. KnownNat n
+    => Vector v n a
+    -> v a
+pattern SomeSized v <- ((`withSized` SV_) -> SV_ v)
+  where
+    SomeSized v = fromSized v
+{-# complete SomeSized :: Boxed.Vector    #-}
+{-# complete SomeSized :: Unboxed.Vector  #-}
+{-# complete SomeSized :: Storable.Vector #-}
 
 instance (VG.Vector v a, Num a, KnownNat n) => Num (Vector v n a) where
     (+)         = zipWith (+)
diff --git a/src/Data/Vector/Generic/Sized/Internal.hs b/src/Data/Vector/Generic/Sized/Internal.hs
--- a/src/Data/Vector/Generic/Sized/Internal.hs
+++ b/src/Data/Vector/Generic/Sized/Internal.hs
@@ -9,18 +9,40 @@
 
 module Data.Vector.Generic.Sized.Internal
   ( Vector(..)
-  ) where
+  )
+where
 
-import           Control.DeepSeq      (NFData)
-import           Data.Data            (Data, Typeable)
-import           Data.Functor.Classes (Eq1, Ord1, Show1)
-import           Data.Vector as V     (and, foldl', null, zipWith, zipWith3)
-import qualified Data.Vector.Generic as VG (Vector, convert, empty, fromList,
-                                      toList)
-import           GHC.Arr              (Ix (inRange, range, unsafeIndex,
-                                      unsafeRangeSize))
-import           GHC.Generics         (Generic)
-import           GHC.TypeLits         (Nat)
+import           Control.DeepSeq                ( NFData )
+import           Data.Data                      ( Data
+                                                , Typeable
+                                                )
+import           Data.Functor.Classes           ( Eq1
+                                                , Ord1
+                                                , Show1
+                                                )
+import           Data.Vector                   as V
+                                                ( and
+                                                , foldl'
+                                                , null
+                                                , zipWith
+                                                , zipWith3
+                                                )
+import qualified Data.Vector.Generic           as VG
+                                                ( Vector
+                                                , convert
+                                                , empty
+                                                , fromList
+                                                , toList
+                                                )
+import           GHC.Arr                        ( Ix
+                                                  ( inRange
+                                                  , range
+                                                  , unsafeIndex
+                                                  , unsafeRangeSize
+                                                  )
+                                                )
+import           GHC.Generics                   ( Generic )
+import           GHC.TypeLits                   ( Nat )
 
 -- | A wrapper to tag vectors with a type level length.
 --
@@ -38,31 +60,41 @@
   range (Vector l, Vector u) = Vector <$> enumerate ranges
    where
     ranges = V.zipWith (curry range) lc uc
-    lc = VG.convert l
-    uc = VG.convert u
-    enumerate v
-      | V.null v = [VG.empty]
-      | otherwise = map VG.fromList $ enumerate' (VG.toList v)
-    enumerate' [] = [[]]
-    enumerate' (xs:xss) = [ x : xs' | x <- xs, xs' <- enumerate' xss ]
+    lc     = VG.convert l
+    uc     = VG.convert u
+    enumerate v | V.null v  = [VG.empty]
+                | otherwise = map VG.fromList $ enumerate' (VG.toList v)
+    enumerate' []         = [[]]
+    enumerate' (xs : xss) = [ x : xs' | x <- xs, xs' <- enumerate' xss ]
 
-  -- index/unsafeIndex is consistent with
-  -- index :: ((a,..,a), (a,..,a)) -> (a,..,a) -> Int
+-- index/unsafeIndex is consistent with
+-- index :: ((a,..,a), (a,..,a)) -> (a,..,a) -> Int
   unsafeIndex (Vector l, Vector u) (Vector i) = V.foldl' f 0 v
    where
     f acc (index', rangeSize') = acc * rangeSize' + index'
-    v = V.zipWith3 indexAndRangeSize lc uc ic
-    lc = VG.convert l
-    uc = VG.convert u
-    ic = VG.convert i
-    indexAndRangeSize l' u' i' = let b' = (l', u')
-                                 in  (unsafeIndex b' i', unsafeRangeSize b')
+    v            = V.zipWith3 indexAndRangeSize lc uc ic
+    (lc, uc, ic) = convert3 l u i
+    indexAndRangeSize l' u' i' =
+      let b' = (l', u') in (unsafeIndex b' i', unsafeRangeSize b')
 
-  -- i is in range (l, u) if, and only if, that is true for all elements,
-  -- element-by-element
-  inRange (Vector l, Vector u) (Vector i) =
-    V.and $ V.zipWith3 (curry inRange) lc uc ic
-   where
-    lc = VG.convert l
-    uc = VG.convert u
-    ic = VG.convert i
+-- i is in range (l, u) if, and only if, that is true for all elements,
+-- element-by-element
+  inRange (Vector l, Vector u) (Vector i) = V.and
+    $ V.zipWith3 (curry inRange) lc uc ic
+    where (lc, uc, ic) = convert3 l u i
+
+-- Conversion helper
+{-# INLINE convert3 #-}
+convert3
+  :: ( VG.Vector v1 a
+     , VG.Vector w1 a
+     , VG.Vector v2 b
+     , VG.Vector w2 b
+     , VG.Vector v3 c
+     , VG.Vector w3 c
+     )
+  => v1 a
+  -> v2 b
+  -> v3 c
+  -> (w1 a, w2 b, w3 c)
+convert3 v1 v2 v3 = (VG.convert v1, VG.convert v2, VG.convert v3)
diff --git a/src/Data/Vector/Mutable/Sized.hs b/src/Data/Vector/Mutable/Sized.hs
--- a/src/Data/Vector/Mutable/Sized.hs
+++ b/src/Data/Vector/Mutable/Sized.hs
@@ -6,12 +6,12 @@
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'
- specialized to 'Data.Vector.Mutable'
+ specialized to 'Data.Vector.Mutable'.
 
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
@@ -91,7 +91,7 @@
 
 
 -- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use
--- 'Data.Vector.Storable.Mutable'
+-- 'Data.Vector.Storable.Mutable'.
 type MVector = VGM.MVector VM.MVector
 
 -- * Accessors
@@ -110,7 +110,7 @@
 length' = VGM.length'
 {-# inline length' #-}
 
--- | /O(1)/ Check whether the mutable vector is empty
+-- | /O(1)/ Check whether the mutable vector is empty.
 null :: forall n s a. (KnownNat n)
        => MVector n s a -> Bool
 null = VGM.null
@@ -152,47 +152,47 @@
 tail = VGM.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n k s a. KnownNat n
      => MVector (n+k) s a -> MVector n s a
 take = VGM.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n k s a p. KnownNat n
       => p n -> MVector (n+k) s a -> MVector n s a
 take' = VGM.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n k s a. KnownNat n
      => MVector (n+k) s a -> MVector k s a
 drop = VGM.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- givel explicitly as a 'Proxy' argument.
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
+-- given explicitly as a 'Proxy' argument.
 drop' :: forall n k s a p. KnownNat n
       => p n -> MVector (n+k) s a -> MVector k s a
 drop' = VGM.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall n m s a. KnownNat n
         => MVector (n+m) s a -> (MVector n s a, MVector m s a)
 splitAt = VGM.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m s a p. KnownNat n
          => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)
@@ -201,9 +201,7 @@
 
 -- ** Overlaps
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- inferred from the type.
+-- | /O(1)/ Check if two vectors overlap. 
 overlaps :: forall n k s a. ()
          => MVector n s a
          -> MVector k s a
@@ -346,13 +344,13 @@
 unsafeModify = VGM.unsafeModify
 {-# inline unsafeModify #-}
 
--- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.
+-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.
 swap :: forall n m a. PrimMonad m
      => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
 swap = VGM.swap
 {-# inline swap #-}
 
--- | /O(1)/ Swap the elements at a given 'Int' position without bounds
+-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds
 -- checking.
 unsafeSwap :: forall n m a. PrimMonad m
            => MVector n (PrimState m) a -> Int -> Int -> m ()
@@ -383,7 +381,7 @@
 #if MIN_VERSION_vector(0,12,0)
 -- * Modifying vectors
 
--- | Compute the next (lexicographically) permutation of a given vector
+-- | Compute the next permutation (lexicographically) of a given vector
 -- in-place.  Returns 'False' when the input is the last permutation.
 nextPermutation :: forall n e m. (Ord e, PrimMonad m)
                 => MVector n (PrimState m) e -> m Bool
@@ -431,7 +429,7 @@
 
 -- | Convert a 'Data.Vector.Generic.Mutable.MVector' into
 -- a 'Data.Vector.Generic.Mutable.Sized.MVector' if it has the correct
--- size, otherwise return Nothing.
+-- size, otherwise return 'Nothing'.
 --
 -- Note that this does no copying; the returned 'MVector' is a reference to
 -- the exact same vector in memory as the given one, and any modifications
@@ -470,5 +468,3 @@
 fromSized :: MVector n s a -> VM.MVector s a
 fromSized = VGM.fromSized
 {-# inline fromSized #-}
-
-
diff --git a/src/Data/Vector/Sized.hs b/src/Data/Vector/Sized.hs
--- a/src/Data/Vector/Sized.hs
+++ b/src/Data/Vector/Sized.hs
@@ -4,6 +4,7 @@
 {-# LANGUAGE RankNTypes                 #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
 {-# LANGUAGE TypeOperators              #-}
+{-# LANGUAGE PatternSynonyms            #-}
 {-# LANGUAGE CPP                        #-}
 
 #if MIN_VERSION_base(4,12,0)
@@ -17,12 +18,13 @@
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
 module Data.Vector.Sized
  ( Vector
+  , pattern SomeSized
   , VM.MVector
    -- * Accessors
    -- ** Length information
@@ -259,7 +261,7 @@
                         showsPrec )
 
 -- | 'Data.Vector.Generic.Sized.Vector' specialized to use
--- 'Data.Vector'
+-- 'Data.Vector'.
 type Vector = V.Vector VU.Vector
 
 -- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
@@ -306,7 +308,7 @@
 index' = V.index'
 {-# inline index' #-}
 
--- | /O(1)/ Indexing using an Int without bounds checking.
+-- | /O(1)/ Indexing using an 'Int' without bounds checking.
 unsafeIndex :: forall n a. ()
       => Vector n a -> Int -> a
 unsafeIndex = V.unsafeIndex
@@ -340,36 +342,36 @@
 _last = V._last
 {-# inline _last #-}
 
--- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
--- an explanation of why this is useful.
+-- | /O(1)/ Safe indexing in a monad. See the documentation for
+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 indexM :: forall n a m. Monad m
       => Vector n a -> Finite n -> m a
 indexM = V.indexM
 {-# inline indexM #-}
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
--- 'VG.indexM' for an explanation of why this is useful.
+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 indexM' :: forall n k a m p. (KnownNat n, Monad m)
       => Vector (n+k) a -> p n -> m a
 indexM' = V.indexM'
 {-# inline indexM' #-}
 
 -- | /O(1)/ Indexing using an Int without bounds checking. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 unsafeIndexM :: forall n a m. Monad m
       => Vector n a -> Int -> m a
 unsafeIndexM = V.unsafeIndexM
 {-# inline unsafeIndexM #-}
 
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 headM :: forall n a m. Monad m
       => Vector (1+n) a -> m a
 headM = V.headM
 {-# inline headM #-}
 
 -- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 lastM :: forall n a m. Monad m
       => Vector (n+1) a -> m a
 lastM = V.lastM
@@ -406,47 +408,47 @@
 tail = V.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n m a. KnownNat n
      => Vector (n+m) a -> Vector n a
 take = V.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n m a p. KnownNat n
       => p n -> Vector (n+m) a -> Vector n a
 take' = V.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n m a. KnownNat n
      => Vector (n+m) a -> Vector m a
 drop = V.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall n m a p. KnownNat n
       => p n -> Vector (n+m) a -> Vector m a
 drop' = V.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall n m a. KnownNat n
         => Vector (n+m) a -> (Vector n a, Vector m a)
 splitAt = V.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m a p. KnownNat n
          => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
@@ -471,9 +473,11 @@
 singleton = V.singleton
 {-# inline singleton #-}
 
--- | /O(n)/ Construct a vector in a type safe manner
+-- | /O(n)/ Construct a vector in a type safe manner.
+-- @
 --   fromTuple (1,2) :: Vector 2 Int
 --   fromTuple ("hey", "what's", "going", "on") :: Vector 4 String
+-- @
 fromTuple :: forall input length ty.
              (IndexedListLiterals input length ty, KnownNat length)
           => input -> Vector length ty
@@ -507,14 +511,14 @@
 generate' = V.generate'
 {-# inline generate' #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is original value.
 -- The length is inferred from the type.
 iterateN :: forall n a. KnownNat n
          => (a -> a) -> a -> Vector n a
 iterateN = V.iterateN
 {-# inline iterateN #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
 iterateN' :: forall n a p. KnownNat n
           => p n -> (a -> a) -> a -> Vector n a
@@ -558,7 +562,7 @@
 --
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is inferred from the
+-- the generator function to the a seed. The length is inferred from the
 -- type.
 unfoldrN :: forall n a b. KnownNat n
          => (b -> (a, b)) -> b -> Vector n a
@@ -566,7 +570,7 @@
 {-# inline unfoldrN #-}
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is given explicitly
+-- the generator function to the a seed. The length is given explicitly
 -- as a 'Proxy' argument.
 unfoldrN' :: forall n a b p. KnownNat n
           => p n -> (b -> (a, b)) -> b -> Vector n a
@@ -577,29 +581,29 @@
 -- ** Enumeration
 --
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is inferred from the type.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length  is inferred from the type.
 enumFromN :: forall n a. (KnownNat n, Num a)
           => a -> Vector n a
 enumFromN = V.enumFromN
 {-# inline enumFromN #-}
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is given explicitly as a 'Proxy' argument.
 enumFromN' :: forall n a p. (KnownNat n, Num a)
            => a -> p n -> Vector n a
 enumFromN' = V.enumFromN'
 {-# inline enumFromN' #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is inferred from the type.
+-- @x+2y@, ... , @x + (n - 1)y@. The length is inferred from the type.
 enumFromStepN :: forall n a. (KnownNat n, Num a)
           => a -> a -> Vector n a
 enumFromStepN = V.enumFromStepN
 {-# inline enumFromStepN #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- @x+2y@, ... , @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.
 enumFromStepN' :: forall n a p. (KnownNat n, Num a)
                => a -> a -> p n -> Vector n a
 enumFromStepN' = V.enumFromStepN'
@@ -790,7 +794,7 @@
 -- ** Permutations
 --
 
--- | /O(n)/ Reverse a vector
+-- | /O(n)/ Reverse a vector.
 reverse ::  Vector n a -> Vector n a
 reverse = V.reverse
 {-# inline reverse #-}
@@ -821,7 +825,7 @@
 -- ** Indexing
 --
 
--- | /O(n)/ Pair each element in a vector with its index
+-- | /O(n)/ Pair each element in a vector with its index.
 indexed :: Vector n a -> Vector n (Finite n,a)
 indexed = V.indexed
 {-# inline indexed #-}
@@ -830,12 +834,12 @@
 -- ** Mapping
 --
 
--- | /O(n)/ Map a function over a vector
+-- | /O(n)/ Map a function over a vector.
 map :: (a -> b) -> Vector n a -> Vector n b
 map = V.map
 {-# inline map #-}
 
--- | /O(n)/ Apply a function to every element of a vector and its index
+-- | /O(n)/ Apply a function to every element of a vector and its index.
 imap :: (Finite n -> a -> b) -> Vector n a -> Vector n b
 imap = V.imap
 {-# inline imap #-}
@@ -851,25 +855,25 @@
 --
 
 -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
--- vector of results
+-- vector of results.
 mapM :: Monad m => (a -> m b) -> Vector n a -> m (Vector n b)
 mapM = V.mapM
 {-# inline mapM #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, yielding a vector of results
+-- index, yielding a vector of results.
 imapM :: Monad m => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)
 imapM = V.imapM
 {-# inline imapM #-}
 
 -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
--- results
+-- results.
 mapM_ :: Monad m => (a -> m b) -> Vector n a -> m ()
 mapM_ = V.mapM_
 {-# inline mapM_ #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, ignoring the results
+-- index, ignoring the results.
 imapM_ :: Monad m => (Finite n -> a -> m b) -> Vector n a -> m ()
 imapM_ = V.imapM_
 {-# inline imapM_ #-}
@@ -977,7 +981,7 @@
 izipWith6 = V.izipWith6
 {-# inline izipWith6 #-}
 
--- | /O(n)/ Zip two vectors of the same length
+-- | /O(n)/ Zip two vectors of the same length.
 zip :: Vector n a -> Vector n b -> Vector n (a, b)
 zip = V.zip
 {-# inline zip #-}
@@ -1018,27 +1022,27 @@
 --
 
 -- | /O(n)/ Zip the two vectors of the same length with the monadic action and
--- yield a vector of results
+-- yield a vector of results.
 zipWithM :: Monad m
          => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 zipWithM = V.zipWithM
 {-# inline zipWithM #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes the
--- element index and yield a vector of results
+-- element index and yield a vector of results.
 izipWithM :: Monad m
          => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 izipWithM = V.izipWithM
 {-# inline izipWithM #-}
 
--- | /O(n)/ Zip the two vectors with the monadic action and ignore the results
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.
 zipWithM_ :: Monad m
           => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 zipWithM_ = V.zipWithM_
 {-# inline zipWithM_ #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes
--- the element index and ignore the results
+-- the element index and ignore the results.
 izipWithM_ :: Monad m
            => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 izipWithM_ = V.izipWithM_
@@ -1078,13 +1082,13 @@
 
 
 infix 4 `elem`
--- | /O(n)/ Check if the vector contains an element
+-- | /O(n)/ Check if the vector contains an element.
 elem :: Eq a => a -> Vector n a -> Bool
 elem = V.elem
 {-# inline elem #-}
 
 infix 4 `notElem`
--- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').
 notElem :: Eq a => a -> Vector n a -> Bool
 notElem = V.notElem
 {-# inline notElem #-}
@@ -1112,64 +1116,64 @@
 -- * Folding
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Left fold
+-- | /O(n)/ Left fold.
 foldl :: (a -> b -> a) -> a -> Vector n b -> a
 foldl = V.foldl
 {-# inline foldl #-}
 
--- | /O(n)/ Left fold on non-empty vectors
+-- | /O(n)/ Left fold on non-empty vectors.
 foldl1 :: (a -> a -> a) -> Vector (1+n) a -> a
 foldl1 = V.foldl1
 {-# inline foldl1 #-}
 
--- | /O(n)/ Left fold with strict accumulator
+-- | /O(n)/ Left fold with strict accumulator.
 foldl' :: (a -> b -> a) -> a -> Vector n b -> a
 foldl' = V.foldl'
 {-# inline foldl' #-}
 
--- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.
 foldl1' :: (a -> a -> a) -> Vector (1+n) a -> a
 foldl1' = V.foldl1'
 {-# inline foldl1' #-}
 
--- | /O(n)/ Right fold
+-- | /O(n)/ Right fold.
 foldr :: (a -> b -> b) -> b -> Vector n a -> b
 foldr = V.foldr
 {-# inline foldr #-}
 
--- | /O(n)/ Right fold on non-empty vectors
+-- | /O(n)/ Right fold on non-empty vectors.
 foldr1 :: (a -> a -> a) -> Vector (n+1) a -> a
 foldr1 = V.foldr1
 {-# inline foldr1 #-}
 
--- | /O(n)/ Right fold with a strict accumulator
+-- | /O(n)/ Right fold with a strict accumulator.
 foldr' :: (a -> b -> b) -> b -> Vector n a -> b
 foldr' = V.foldr'
 {-# inline foldr' #-}
 
--- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.
 foldr1' :: (a -> a -> a) -> Vector (n+1) a -> a
 foldr1' = V.foldr1'
 {-# inline foldr1' #-}
 
--- | /O(n)/ Left fold (function applied to each element and its index)
+-- | /O(n)/ Left fold (function applied to each element and its index).
 ifoldl :: (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl = V.ifoldl
 {-# inline ifoldl #-}
 
 -- | /O(n)/ Left fold with strict accumulator (function applied to each element
--- and its index)
+-- and its index).
 ifoldl' :: (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl' = V.ifoldl'
 {-# inline ifoldl' #-}
 
--- | /O(n)/ Right fold (function applied to each element and its index)
+-- | /O(n)/ Right fold (function applied to each element and its index).
 ifoldr :: (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr = V.ifoldr
 {-# inline ifoldr #-}
 
 -- | /O(n)/ Right fold with strict accumulator (function applied to each
--- element and its index)
+-- element and its index).
 ifoldr' :: (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr' = V.ifoldr'
 {-# inline ifoldr' #-}
@@ -1186,22 +1190,22 @@
 any = V.any
 {-# inline any #-}
 
--- | /O(n)/ Check if all elements are 'True'
+-- | /O(n)/ Check if all elements are 'True'.
 and :: Vector n Bool -> Bool
 and = V.and
 {-# inline and #-}
 
--- | /O(n)/ Check if any element is 'True'
+-- | /O(n)/ Check if any element is 'True'.
 or :: Vector n Bool -> Bool
 or = V.or
 {-# inline or #-}
 
--- | /O(n)/ Compute the sum of the elements
+-- | /O(n)/ Compute the sum of the elements.
 sum :: (Num a) => Vector n a -> a
 sum = V.sum
 {-# inline sum #-}
 
--- | /O(n)/ Compute the produce of the elements
+-- | /O(n)/ Compute the product of the elements.
 product :: (Num a) => Vector n a -> a
 product = V.product
 {-# inline product #-}
@@ -1252,78 +1256,78 @@
 
 -- ** Monadic folds
 
--- | /O(n)/ Monadic fold
+-- | /O(n)/ Monadic fold.
 foldM :: Monad m => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM = V.foldM
 {-# inline foldM #-}
 
--- | /O(n)/ Monadic fold (action applied to each element and its index)
+-- | /O(n)/ Monadic fold (action applied to each element and its index).
 ifoldM :: Monad m => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM = V.ifoldM
 {-# inline ifoldM #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors
+-- | /O(n)/ Monadic fold over non-empty vectors.
 fold1M :: Monad m => (a -> a -> m a) -> Vector (1+n) a -> m a
 fold1M = V.fold1M
 {-# inline fold1M #-}
 
--- | /O(n)/ Monadic fold with strict accumulator
+-- | /O(n)/ Monadic fold with strict accumulator.
 foldM' :: Monad m => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM' = V.foldM'
 {-# inline foldM' #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator (action applied to each
--- element and its index)
+-- element and its index).
 ifoldM' :: Monad m => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM' = V.ifoldM'
 {-# inline ifoldM' #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.
 fold1M' :: Monad m => (a -> a -> m a) -> Vector (n+1) a -> m a
 fold1M' = V.fold1M'
 {-# inline fold1M' #-}
 
--- | /O(n)/ Monadic fold that discards the result
+-- | /O(n)/ Monadic fold that discards the result.
 foldM_ :: Monad m => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM_ = V.foldM_
 {-# inline foldM_ #-}
 
 -- | /O(n)/ Monadic fold that discards the result (action applied to
--- each element and its index)
+-- each element and its index).
 ifoldM_ :: Monad m => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM_ = V.ifoldM_
 {-# inline ifoldM_ #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.
 fold1M_ :: Monad m => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M_ = V.fold1M_
 {-# inline fold1M_ #-}
 
--- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result.
 foldM'_ :: Monad m => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM'_ = V.foldM'_
 {-# inline foldM'_ #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator that discards the result
--- (action applied to each element and its index)
+-- (action applied to each element and its index).
 ifoldM'_ :: Monad m => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM'_ = V.ifoldM'_
 {-# inline ifoldM'_ #-}
 
 -- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
--- that discards the result
+-- that discards the result.
 fold1M'_ :: Monad m => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M'_ = V.fold1M'_
 {-# inline fold1M'_ #-}
 
 -- ** Monadic sequencing
 
--- | Evaluate each action and collect the results
+-- | Evaluate each action and collect the results.
 sequence :: Monad m => Vector n (m a) -> m (Vector n a)
 sequence = V.sequence
 {-# inline sequence #-}
 
--- | Evaluate each action and discard the results
+-- | Evaluate each action and discard the results.
 sequence_ :: Monad m => Vector n (m a) -> m ()
 sequence_ = V.sequence_
 {-# inline sequence_ #-}
@@ -1332,7 +1336,7 @@
 -- * Prefix sums (scans)
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Prescan
+-- | /O(n)/ Prescan.
 --
 -- @
 -- prescanl f z = 'init' . 'scanl' f z
@@ -1344,78 +1348,78 @@
 prescanl = V.prescanl
 {-# inline prescanl #-}
 
--- | /O(n)/ Prescan with strict accumulator
+-- | /O(n)/ Prescan with strict accumulator.
 prescanl' ::  (a -> b -> a) -> a -> Vector n b -> Vector n a
 prescanl' = V.prescanl'
 {-# inline prescanl' #-}
 
--- | /O(n)/ Scan
+-- | /O(n)/ Scan.
 postscanl ::  (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl = V.postscanl
 {-# inline postscanl #-}
 
--- | /O(n)/ Scan with strict accumulator
+-- | /O(n)/ Scan with strict accumulator.
 postscanl' ::  (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl' = V.postscanl'
 {-# inline postscanl' #-}
 
--- | /O(n)/ Haskell-style scan
+-- | /O(n)/ Haskell-style scan.
 scanl ::  (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl = V.scanl
 {-# inline scanl #-}
 
--- | /O(n)/ Haskell-style scan with strict accumulator
+-- | /O(n)/ Haskell-style scan with strict accumulator.
 scanl' ::  (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl' = V.scanl'
 {-# inline scanl' #-}
 
--- | /O(n)/ Scan over a non-empty vector
+-- | /O(n)/ Scan over a non-empty vector.
 scanl1 :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1 = V.scanl1
 {-# inline scanl1 #-}
 
--- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.
 scanl1' :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1' = V.scanl1'
 {-# inline scanl1' #-}
 
--- | /O(n)/ Right-to-left prescan
+-- | /O(n)/ Right-to-left prescan.
 prescanr ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr = V.prescanr
 {-# inline prescanr #-}
 
--- | /O(n)/ Right-to-left prescan with strict accumulator
+-- | /O(n)/ Right-to-left prescan with strict accumulator.
 prescanr' ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr' = V.prescanr'
 {-# inline prescanr' #-}
 
--- | /O(n)/ Right-to-left scan
+-- | /O(n)/ Right-to-left scan.
 postscanr ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr = V.postscanr
 {-# inline postscanr #-}
 
--- | /O(n)/ Right-to-left scan with strict accumulator
+-- | /O(n)/ Right-to-left scan with strict accumulator.
 postscanr' ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr' = V.postscanr'
 {-# inline postscanr' #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan
+-- | /O(n)/ Right-to-left Haskell-style scan.
 scanr ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr = V.scanr
 {-# inline scanr #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.
 scanr' ::  (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr' = V.scanr'
 {-# inline scanr' #-}
 
--- | /O(n)/ Right-to-left scan over a non-empty vector
+-- | /O(n)/ Right-to-left scan over a non-empty vector.
 scanr1 :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1 = V.scanr1
 {-# inline scanr1 #-}
 
 -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
--- accumulator
+-- accumulator.
 scanr1' :: (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1' = V.scanr1'
 {-# inline scanr1' #-}
@@ -1425,25 +1429,25 @@
 
 -- ** Lists
 
--- | /O(n)/ Convert a vector to a list
+-- | /O(n)/ Convert a vector to a list.
 toList :: Vector n a -> [a]
 toList = V.toList
 {-# inline toList #-}
 
--- | /O(n)/ Convert a list to a vector
+-- | /O(n)/ Convert a list to a vector.
 fromList :: KnownNat n => [a] -> Maybe (Vector n a)
 fromList = V.fromList
 {-# inline fromList #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is inferred from the type.
+-- the resulting vector is inferred from the type.
 fromListN :: forall n a. KnownNat n
           => [a] -> Maybe (Vector n a)
 fromListN = V.fromListN
 {-# inline fromListN #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is given explicitly as a 'Proxy' argument.
+-- the resulting vector is given explicitly as a 'Proxy' argument.
 fromListN' :: forall n a p. KnownNat n
            => p n -> [a] -> Maybe (Vector n a)
 fromListN' = V.fromListN'
@@ -1468,7 +1472,7 @@
        -> m (Vector n a)
 freeze = V.freeze
 
--- | /O(1)/ Unsafely convert a mutable vector to an immutable one withouy
+-- | /O(1)/ Unsafely convert a mutable vector to an immutable one without
 -- copying. The mutable vector may not be used after this operation.
 unsafeFreeze :: PrimMonad m
              => VM.MVector n (PrimState m) a
@@ -1499,7 +1503,7 @@
 
 -- | Convert a 'Data.Vector.Generic.Vector' into a
 -- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
--- return Nothing.
+-- return 'Nothing'.
 toSized :: forall n a. KnownNat n
         => VU.Vector a -> Maybe (Vector n a)
 toSized = V.toSized
@@ -1525,3 +1529,79 @@
 withVectorUnsafe :: (VU.Vector a -> VU.Vector b) -> Vector n a -> Vector n b
 withVectorUnsafe = V.withVectorUnsafe
 {-# inline withVectorUnsafe #-}
+
+-- | Pattern synonym that lets you treat an unsized vector as if it
+-- "contained" a sized vector.  If you pattern match on an unsized vector,
+-- its contents will be the /sized/ vector counterpart.
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc ('SomeSized' v) =
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+--         -- ^ here, v is `Sized.Vector n Int`, and we have
+--                     `'KnownNat' n`
+-- @
+--
+-- The @n@ type variable will be properly instantiated to whatever the
+-- length of the vector is, and you will also have a @'KnownNat' n@
+-- instance available.  You can get @n@ in scope by turning on
+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector
+-- n Int)@.
+--
+-- Without this, you would otherwise have to use 'withSized' to do the same
+-- thing:
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc u = 'withSized' u $ \\v ->
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+-- @
+--
+-- Remember that the type of final result of your function (the @Int@,
+-- here) must /not/ depend on @n@.  However, the types of the intermediate
+-- values are allowed to depend on @n@.
+--
+-- This is /especially/ useful in do blocks, where you can pattern match on
+-- the unsized results of actions, to use the sized vector in the rest of
+-- the do block.  You also get a @'KnownNat' n@ constraint for the
+-- remainder of the do block.
+--
+-- @
+-- -- If you had:
+-- getAVector :: IO (Unsized.Vector Int)
+--
+-- main :: IO ()
+-- main = do
+--     SomeSized v <- getAVector -- v is `Sized.Vector n Int`
+--     -- get n in scope
+--     SomeSized (v :: Sized.Vector n Int) <- getAVector
+--     print v
+-- @
+--
+-- Remember that the final type of the result of the do block ('()', here)
+-- must not depend on @n@.  However, the 
+--
+-- Also useful in ghci, where you can pattern match to get sized vectors
+-- from unsized vectors.
+--
+-- @
+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)
+--              -- ^ v is `Sized.Vector n Int`
+-- @
+--
+-- This enables interactive exploration with sized vectors in ghci, and is
+-- useful for using with other libraries and functions that expect sized
+-- vectors in an interactive setting.
+--
+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci
+-- session using ScopedTypeVariables, like you can with do blocks)
+--
+-- You can also use this as a constructor, to take a sized vector and
+-- "hide" the size, to produce an unsized vector:
+--
+-- @
+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a
+-- @
+pattern SomeSized :: () => KnownNat n => Vector n a -> VU.Vector a
+pattern SomeSized v = V.SomeSized v
+{-# complete SomeSized #-}
diff --git a/src/Data/Vector/Storable/Mutable/Sized.hs b/src/Data/Vector/Storable/Mutable/Sized.hs
--- a/src/Data/Vector/Storable/Mutable/Sized.hs
+++ b/src/Data/Vector/Storable/Mutable/Sized.hs
@@ -6,12 +6,12 @@
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'
- specialized to 'Data.Vector.Storable.Mutable'
+ specialized to 'Data.Vector.Storable.Mutable'.
 
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
@@ -92,7 +92,7 @@
 
 
 -- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use
--- 'Data.Vector.Storable.Mutable'
+-- 'Data.Vector.Storable.Mutable'.
 type MVector = VGM.MVector VSM.MVector
 
 -- * Accessors
@@ -111,7 +111,7 @@
 length' = VGM.length'
 {-# inline length' #-}
 
--- | /O(1)/ Check whether the mutable vector is empty
+-- | /O(1)/ Check whether the mutable vector is empty.
 null :: forall n s a. (KnownNat n)
        => MVector n s a -> Bool
 null = VGM.null
@@ -153,47 +153,47 @@
 tail = VGM.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n k s a. (KnownNat n, Storable a)
      => MVector (n+k) s a -> MVector n s a
 take = VGM.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n k s a p. (KnownNat n, Storable a)
       => p n -> MVector (n+k) s a -> MVector n s a
 take' = VGM.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n k s a. (KnownNat n, Storable a)
      => MVector (n+k) s a -> MVector k s a
 drop = VGM.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall n k s a p. (KnownNat n, Storable a)
       => p n -> MVector (n+k) s a -> MVector k s a
 drop' = VGM.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall n m s a. (KnownNat n, Storable a)
         => MVector (n+m) s a -> (MVector n s a, MVector m s a)
 splitAt = VGM.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m s a p. (KnownNat n, Storable a)
          => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)
@@ -202,9 +202,7 @@
 
 -- ** Overlaps
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- inferred from the type.
+-- | /O(1)/ Check if two vectors overlap. 
 overlaps :: forall n k s a. Storable a
          => MVector n s a
          -> MVector k s a
@@ -347,13 +345,13 @@
 unsafeModify = VGM.unsafeModify
 {-# inline unsafeModify #-}
 
--- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.
+-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.
 swap :: forall n m a. (PrimMonad m, Storable a)
      => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
 swap = VGM.swap
 {-# inline swap #-}
 
--- | /O(1)/ Swap the elements at a given 'Int' position without bounds
+-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds
 -- checking.
 unsafeSwap :: forall n m a. (PrimMonad m, Storable a)
            => MVector n (PrimState m) a -> Int -> Int -> m ()
@@ -384,7 +382,7 @@
 #if MIN_VERSION_vector(0,12,0)
 -- * Modifying vectors
 
--- | Compute the next (lexicographically) permutation of a given vector
+-- | Compute the next permutation (lexicographically) of a given vector
 -- in-place.  Returns 'False' when the input is the last permutation.
 nextPermutation :: forall n e m. (Ord e, PrimMonad m, Storable e)
                 => MVector n (PrimState m) e -> m Bool
diff --git a/src/Data/Vector/Storable/Sized.hs b/src/Data/Vector/Storable/Sized.hs
--- a/src/Data/Vector/Storable/Sized.hs
+++ b/src/Data/Vector/Storable/Sized.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeOperators       #-}
+{-# LANGUAGE PatternSynonyms     #-}
 {-# LANGUAGE CPP                 #-}
 
 #if MIN_VERSION_base(4,12,0)
@@ -13,17 +14,18 @@
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Sized'
- specialized to 'Data.Vector.Storable'
+ specialized to 'Data.Vector.Storable'.
 
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
 module Data.Vector.Storable.Sized
  ( Vector
+  , pattern SomeSized
   , VSM.MVector
    -- * Accessors
    -- ** Length information
@@ -261,7 +263,7 @@
                         showsPrec )
 
 -- | 'Data.Vector.Generic.Sized.Vector' specialized to use
--- 'Data.Vector.Storable'
+-- 'Data.Vector.Storable'.
 type Vector = V.Vector VS.Vector
 
 -- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
@@ -308,7 +310,7 @@
 index' = V.index'
 {-# inline index' #-}
 
--- | /O(1)/ Indexing using an Int without bounds checking.
+-- | /O(1)/ Indexing using an 'Int' without bounds checking.
 unsafeIndex :: forall n a. Storable a
       => Vector n a -> Int -> a
 unsafeIndex = V.unsafeIndex
@@ -345,7 +347,7 @@
 {-# inline _last #-}
 
 
--- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
+-- | /O(1)/ Safe indexing in a monad. See the documentation for 'Data.Vector.Generic.Sized.indexM' for
 -- an explanation of why this is useful.
 indexM :: forall n a m. (Storable a, Monad m)
       => Vector n a -> Finite n -> m a
@@ -353,28 +355,28 @@
 {-# inline indexM #-}
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
--- 'VG.indexM' for an explanation of why this is useful.
+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 indexM' :: forall n k a m p. (KnownNat n, Storable a, Monad m)
       => Vector (n+k) a -> p n -> m a
 indexM' = V.indexM'
 {-# inline indexM' #-}
 
--- | /O(1)/ Indexing using an Int without bounds checking. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- | /O(1)/ Indexing using an 'Int' without bounds checking. See the
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 unsafeIndexM :: forall n a m. (Storable a, Monad m)
       => Vector n a -> Int -> m a
 unsafeIndexM = V.unsafeIndexM
 {-# inline unsafeIndexM #-}
 
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 headM :: forall n a m. (Storable a, Monad m)
       => Vector (1+n) a -> m a
 headM = V.headM
 {-# inline headM #-}
 
 -- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 lastM :: forall n a m. (Storable a, Monad m)
       => Vector (n+1) a -> m a
 lastM = V.lastM
@@ -413,47 +415,47 @@
 tail = V.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n m a. (KnownNat n, Storable a)
      => Vector (n+m) a -> Vector n a
 take = V.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n m a p. (KnownNat n, Storable a)
       => p n -> Vector (n+m) a -> Vector n a
 take' = V.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n m a. (KnownNat n, Storable a)
      => Vector (n+m) a -> Vector m a
 drop = V.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall n m a p. (KnownNat n, Storable a)
       => p n -> Vector (n+m) a -> Vector m a
 drop' = V.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall n m a. (KnownNat n, Storable a)
         => Vector (n+m) a -> (Vector n a, Vector m a)
 splitAt = V.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements paired with the remainder without
+-- copying. The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m a p. (KnownNat n, Storable a)
          => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
@@ -481,8 +483,10 @@
 {-# inline singleton #-}
 
 -- | /O(n)/ Construct a vector in a type safe manner
+-- @
 --   fromTuple (1,2) :: Vector 2 Int
 --   fromTuple ("hey", "what's", "going", "on") :: Vector 4 String
+-- @
 fromTuple :: forall a input length.
              (Storable a, IndexedListLiterals input length a, KnownNat length)
           => input -> Vector length a
@@ -517,14 +521,14 @@
 generate' = V.generate'
 {-# inline generate' #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.
 -- The length is inferred from the type.
 iterateN :: forall n a. (KnownNat n, Storable a)
          => (a -> a) -> a -> Vector n a
 iterateN = V.iterateN
 {-# inline iterateN #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply function @n@ times to value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
 iterateN' :: forall n a p. (KnownNat n, Storable a)
           => p n -> (a -> a) -> a -> Vector n a
@@ -550,14 +554,14 @@
 {-# inline replicateM' #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is inferred from the type.
+-- each index where @n@ is inferred from the type.
 generateM :: forall n m a. (KnownNat n, Storable a, Monad m)
           => (Finite n -> m a) -> m (Vector n a)
 generateM = V.generateM
 {-# inline generateM #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is given explicitly as a 'Proxy' argument.
+-- each index where @n@ is given explicitly as a 'Proxy' argument.
 generateM' :: forall n m a p. (KnownNat n, Storable a, Monad m)
            => p n -> (Finite n -> m a) -> m (Vector n a)
 generateM' = V.generateM'
@@ -568,7 +572,7 @@
 --
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is inferred from the
+-- the generator function to the a seed. The length is inferred from the
 -- type.
 unfoldrN :: forall n a b. (KnownNat n, Storable a)
          => (b -> (a, b)) -> b -> Vector n a
@@ -576,7 +580,7 @@
 {-# inline unfoldrN #-}
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is given explicitly
+-- the generator function to the a seed. The length is given explicitly
 -- as a 'Proxy' argument.
 unfoldrN' :: forall n a b p. (KnownNat n, Storable a)
           => p n -> (b -> (a, b)) -> b -> Vector n a
@@ -587,29 +591,29 @@
 -- ** Enumeration
 --
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is inferred from the type.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is inferred from the type.
 enumFromN :: forall n a. (KnownNat n, Storable a, Num a)
           => a -> Vector n a
 enumFromN = V.enumFromN
 {-# inline enumFromN #-}
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is given explicitly as a 'Proxy' argument.
 enumFromN' :: forall n a p. (KnownNat n, Storable a, Num a)
            => a -> p n -> Vector n a
 enumFromN' = V.enumFromN'
 {-# inline enumFromN' #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is inferred from the type.
+-- @x+2y@, ..., @x + (n - 1)y@. The length is inferred from the type.
 enumFromStepN :: forall n a. (KnownNat n, Storable a, Num a)
           => a -> a -> Vector n a
 enumFromStepN = V.enumFromStepN
 {-# inline enumFromStepN #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- @x+2y@, ..., @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.
 enumFromStepN' :: forall n a p. (KnownNat n, Storable a, Num a)
                => a -> a -> p n -> Vector n a
 enumFromStepN' = V.enumFromStepN'
@@ -815,7 +819,7 @@
 -- ** Permutations
 --
 
--- | /O(n)/ Reverse a vector
+-- | /O(n)/ Reverse a vector.
 reverse :: (Storable a) => Vector n a -> Vector n a
 reverse = V.reverse
 {-# inline reverse #-}
@@ -848,7 +852,7 @@
 -- ** Indexing
 --
 
--- | /O(n)/ Pair each element in a vector with its index
+-- | /O(n)/ Pair each element in a vector with its index.
 indexed :: (Storable a, Storable (Int, a), Storable (Finite n, a))
         => Vector n a -> Vector n (Finite n,a)
 indexed = V.indexed
@@ -858,13 +862,13 @@
 -- ** Mapping
 --
 
--- | /O(n)/ Map a function over a vector
+-- | /O(n)/ Map a function over a vector.
 map :: (Storable a, Storable b)
     => (a -> b) -> Vector n a -> Vector n b
 map = V.map
 {-# inline map #-}
 
--- | /O(n)/ Apply a function to every element of a vector and its index
+-- | /O(n)/ Apply a function to every element of a vector and its index.
 imap :: (Storable a, Storable b)
      => (Finite n -> a -> b) -> Vector n a -> Vector n b
 imap = V.imap
@@ -882,27 +886,27 @@
 --
 
 -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
--- vector of results
+-- vector of results.
 mapM :: (Monad m, Storable a, Storable b)
       => (a -> m b) -> Vector n a -> m (Vector n b)
 mapM = V.mapM
 {-# inline mapM #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, yielding a vector of results
+-- index, yielding a vector of results.
 imapM :: (Monad m, Storable a, Storable b)
       => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)
 imapM = V.imapM
 {-# inline imapM #-}
 
 -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
--- results
+-- results.
 mapM_ :: (Monad m, Storable a) => (a -> m b) -> Vector n a -> m ()
 mapM_ = V.mapM_
 {-# inline mapM_ #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, ignoring the results
+-- index, ignoring the results.
 imapM_ :: (Monad m, Storable a) => (Finite n -> a -> m b) -> Vector n a -> m ()
 imapM_ = V.imapM_
 {-# inline imapM_ #-}
@@ -1021,7 +1025,7 @@
 izipWith6 = V.izipWith6
 {-# inline izipWith6 #-}
 
--- | /O(n)/ Zip two vectors of the same length
+-- | /O(n)/ Zip two vectors of the same length.
 zip :: (Storable a, Storable b, Storable (a,b))
     => Vector n a -> Vector n b -> Vector n (a, b)
 zip = V.zip
@@ -1067,27 +1071,27 @@
 --
 
 -- | /O(n)/ Zip the two vectors of the same length with the monadic action and
--- yield a vector of results
+-- yield a vector of results.
 zipWithM :: (Monad m, Storable a, Storable b, Storable c)
          => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 zipWithM = V.zipWithM
 {-# inline zipWithM #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes the
--- element index and yield a vector of results
+-- element index and yield a vector of results.
 izipWithM :: (Monad m, Storable a, Storable b, Storable c)
          => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 izipWithM = V.izipWithM
 {-# inline izipWithM #-}
 
--- | /O(n)/ Zip the two vectors with the monadic action and ignore the results
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.
 zipWithM_ :: (Monad m, Storable a, Storable b)
           => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 zipWithM_ = V.zipWithM_
 {-# inline zipWithM_ #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes
--- the element index and ignore the results
+-- the element index and ignore the results.
 izipWithM_ :: (Monad m, Storable a, Storable b)
            => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 izipWithM_ = V.izipWithM_
@@ -1135,13 +1139,13 @@
 
 
 infix 4 `elem`
--- | /O(n)/ Check if the vector contains an element
+-- | /O(n)/ Check if the vector contains an element.
 elem :: (Storable a, Eq a) => a -> Vector n a -> Bool
 elem = V.elem
 {-# inline elem #-}
 
 infix 4 `notElem`
--- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').
 notElem :: (Storable a, Eq a) => a -> Vector n a -> Bool
 notElem = V.notElem
 {-# inline notElem #-}
@@ -1169,64 +1173,64 @@
 -- * Folding
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Left fold
+-- | /O(n)/ Left fold.
 foldl :: Storable b => (a -> b -> a) -> a -> Vector n b -> a
 foldl = V.foldl
 {-# inline foldl #-}
 
--- | /O(n)/ Left fold on non-empty vectors
+-- | /O(n)/ Left fold on non-empty vectors.
 foldl1 :: Storable a => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1 = V.foldl1
 {-# inline foldl1 #-}
 
--- | /O(n)/ Left fold with strict accumulator
+-- | /O(n)/ Left fold with strict accumulator.
 foldl' :: Storable b => (a -> b -> a) -> a -> Vector n b -> a
 foldl' = V.foldl'
 {-# inline foldl' #-}
 
--- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.
 foldl1' :: Storable a => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1' = V.foldl1'
 {-# inline foldl1' #-}
 
--- | /O(n)/ Right fold
+-- | /O(n)/ Right fold.
 foldr :: Storable a => (a -> b -> b) -> b -> Vector n a -> b
 foldr = V.foldr
 {-# inline foldr #-}
 
--- | /O(n)/ Right fold on non-empty vectors
+-- | /O(n)/ Right fold on non-empty vectors.
 foldr1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> a
 foldr1 = V.foldr1
 {-# inline foldr1 #-}
 
--- | /O(n)/ Right fold with a strict accumulator
+-- | /O(n)/ Right fold with a strict accumulator.
 foldr' :: Storable a => (a -> b -> b) -> b -> Vector n a -> b
 foldr' = V.foldr'
 {-# inline foldr' #-}
 
--- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.
 foldr1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> a
 foldr1' = V.foldr1'
 {-# inline foldr1' #-}
 
--- | /O(n)/ Left fold (function applied to each element and its index)
+-- | /O(n)/ Left fold (function applied to each element and its index).
 ifoldl :: Storable b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl = V.ifoldl
 {-# inline ifoldl #-}
 
 -- | /O(n)/ Left fold with strict accumulator (function applied to each element
--- and its index)
+-- and its index).
 ifoldl' :: Storable b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl' = V.ifoldl'
 {-# inline ifoldl' #-}
 
--- | /O(n)/ Right fold (function applied to each element and its index)
+-- | /O(n)/ Right fold (function applied to each element and its index).
 ifoldr :: Storable a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr = V.ifoldr
 {-# inline ifoldr #-}
 
 -- | /O(n)/ Right fold with strict accumulator (function applied to each
--- element and its index)
+-- element and its index).
 ifoldr' :: Storable a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr' = V.ifoldr'
 {-# inline ifoldr' #-}
@@ -1253,12 +1257,12 @@
 or = V.or
 {-# inline or #-}
 
--- | /O(n)/ Compute the sum of the elements
+-- | /O(n)/ Compute the sum of the elements.
 sum :: (Storable a, Num a) => Vector n a -> a
 sum = V.sum
 {-# inline sum #-}
 
--- | /O(n)/ Compute the produce of the elements
+-- | /O(n)/ Compute the product of the elements.
 product :: (Storable a, Num a) => Vector n a -> a
 product = V.product
 {-# inline product #-}
@@ -1313,74 +1317,74 @@
 
 -- ** Monadic folds
 
--- | /O(n)/ Monadic fold
+-- | /O(n)/ Monadic fold.
 foldM :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM = V.foldM
 {-# inline foldM #-}
 
--- | /O(n)/ Monadic fold (action applied to each element and its index)
+-- | /O(n)/ Monadic fold (action applied to each element and its index).
 ifoldM :: (Monad m, Storable b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM = V.ifoldM
 {-# inline ifoldM #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors
+-- | /O(n)/ Monadic fold over non-empty vectors.
 fold1M :: (Monad m, Storable a)
        => (a -> a -> m a) -> Vector (1+n) a -> m a
 fold1M = V.fold1M
 {-# inline fold1M #-}
 
--- | /O(n)/ Monadic fold with strict accumulator
+-- | /O(n)/ Monadic fold with strict accumulator.
 foldM' :: (Monad m, Storable b) => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM' = V.foldM'
 {-# inline foldM' #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator (action applied to each
--- element and its index)
+-- element and its index).
 ifoldM' :: (Monad m, Storable b)
         => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM' = V.ifoldM'
 {-# inline ifoldM' #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.
 fold1M' :: (Monad m, Storable a)
         => (a -> a -> m a) -> Vector (n+1) a -> m a
 fold1M' = V.fold1M'
 {-# inline fold1M' #-}
 
--- | /O(n)/ Monadic fold that discards the result
+-- | /O(n)/ Monadic fold that discards the result.
 foldM_ :: (Monad m, Storable b)
        => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM_ = V.foldM_
 {-# inline foldM_ #-}
 
 -- | /O(n)/ Monadic fold that discards the result (action applied to
--- each element and its index)
+-- each element and its index).
 ifoldM_ :: (Monad m, Storable b)
         => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM_ = V.ifoldM_
 {-# inline ifoldM_ #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.
 fold1M_ :: (Monad m, Storable a)
         => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M_ = V.fold1M_
 {-# inline fold1M_ #-}
 
--- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result.
 foldM'_ :: (Monad m, Storable b)
         => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM'_ = V.foldM'_
 {-# inline foldM'_ #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator that discards the result
--- (action applied to each element and its index)
+-- (action applied to each element and its index).
 ifoldM'_ :: (Monad m, Storable b)
          => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM'_ = V.ifoldM'_
 {-# inline ifoldM'_ #-}
 
 -- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
--- that discards the result
+-- that discards the result.
 fold1M'_ :: (Monad m, Storable a)
          => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M'_ = V.fold1M'_
@@ -1388,13 +1392,13 @@
 
 -- ** Monadic sequencing
 
--- | Evaluate each action and collect the results
+-- | Evaluate each action and collect the results.
 sequence :: (Monad m, Storable a, Storable (m a))
          => Vector n (m a) -> m (Vector n a)
 sequence = V.sequence
 {-# inline sequence #-}
 
--- | Evaluate each action and discard the results
+-- | Evaluate each action and discard the results.
 sequence_ :: (Monad m, Storable (m a)) => Vector n (m a) -> m ()
 sequence_ = V.sequence_
 {-# inline sequence_ #-}
@@ -1403,7 +1407,7 @@
 -- * Prefix sums (scans)
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Prescan
+-- | /O(n)/ Prescan.
 --
 -- @
 -- prescanl f z = 'init' . 'scanl' f z
@@ -1415,78 +1419,78 @@
 prescanl = V.prescanl
 {-# inline prescanl #-}
 
--- | /O(n)/ Prescan with strict accumulator
+-- | /O(n)/ Prescan with strict accumulator.
 prescanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 prescanl' = V.prescanl'
 {-# inline prescanl' #-}
 
--- | /O(n)/ Scan
+-- | /O(n)/ Scan.
 postscanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl = V.postscanl
 {-# inline postscanl #-}
 
--- | /O(n)/ Scan with strict accumulator
+-- | /O(n)/ Scan with strict accumulator.
 postscanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl' = V.postscanl'
 {-# inline postscanl' #-}
 
--- | /O(n)/ Haskell-style scan
+-- | /O(n)/ Haskell-style scan.
 scanl :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl = V.scanl
 {-# inline scanl #-}
 
--- | /O(n)/ Haskell-style scan with strict accumulator
+-- | /O(n)/ Haskell-style scan with strict accumulator.
 scanl' :: (Storable a, Storable b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl' = V.scanl'
 {-# inline scanl' #-}
 
--- | /O(n)/ Scan over a non-empty vector
+-- | /O(n)/ Scan over a non-empty vector.
 scanl1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1 = V.scanl1
 {-# inline scanl1 #-}
 
--- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.
 scanl1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1' = V.scanl1'
 {-# inline scanl1' #-}
 
--- | /O(n)/ Right-to-left prescan
+-- | /O(n)/ Right-to-left prescan.
 prescanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr = V.prescanr
 {-# inline prescanr #-}
 
--- | /O(n)/ Right-to-left prescan with strict accumulator
+-- | /O(n)/ Right-to-left prescan with strict accumulator.
 prescanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr' = V.prescanr'
 {-# inline prescanr' #-}
 
--- | /O(n)/ Right-to-left scan
+-- | /O(n)/ Right-to-left scan.
 postscanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr = V.postscanr
 {-# inline postscanr #-}
 
--- | /O(n)/ Right-to-left scan with strict accumulator
+-- | /O(n)/ Right-to-left scan with strict accumulator.
 postscanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr' = V.postscanr'
 {-# inline postscanr' #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan
+-- | /O(n)/ Right-to-left Haskell-style scan.
 scanr :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr = V.scanr
 {-# inline scanr #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.
 scanr' :: (Storable a, Storable b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr' = V.scanr'
 {-# inline scanr' #-}
 
--- | /O(n)/ Right-to-left scan over a non-empty vector
+-- | /O(n)/ Right-to-left scan over a non-empty vector.
 scanr1 :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1 = V.scanr1
 {-# inline scanr1 #-}
 
 -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
--- accumulator
+-- accumulator.
 scanr1' :: Storable a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1' = V.scanr1'
 {-# inline scanr1' #-}
@@ -1496,25 +1500,25 @@
 
 -- ** Lists
 
--- | /O(n)/ Convert a vector to a list
+-- | /O(n)/ Convert a vector to a list.
 toList :: Storable a => Vector n a -> [a]
 toList = V.toList
 {-# inline toList #-}
 
--- | /O(n)/ Convert a list to a vector
+-- | /O(n)/ Convert a list to a vector.
 fromList :: (Storable a, KnownNat n) => [a] -> Maybe (Vector n a)
 fromList = V.fromList
 {-# inline fromList #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is inferred from the type.
+-- the resulting vector is inferred from the type.
 fromListN :: forall n a. (Storable a, KnownNat n)
           => [a] -> Maybe (Vector n a)
 fromListN = V.fromListN
 {-# inline fromListN #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is given explicitly as a 'Proxy' argument.
+-- the resulting vector is given explicitly as a 'Proxy' argument.
 fromListN' :: forall n a p. (Storable a, KnownNat n)
            => p n -> [a] -> Maybe (Vector n a)
 fromListN' = V.fromListN'
@@ -1571,7 +1575,7 @@
 
 -- | Convert a 'Data.Vector.Generic.Vector' into a
 -- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
--- return Nothing.
+-- return 'Nothing'.
 toSized :: forall n a. (Storable a, KnownNat n)
         => VS.Vector a -> Maybe (Vector n a)
 toSized = V.toSized
@@ -1601,3 +1605,78 @@
 withVectorUnsafe = V.withVectorUnsafe
 {-# inline withVectorUnsafe #-}
 
+-- | Pattern synonym that lets you treat an unsized vector as if it
+-- "contained" a sized vector.  If you pattern match on an unsized vector,
+-- its contents will be the /sized/ vector counterpart.
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc ('SomeSized' v) =
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+--         -- ^ here, v is `Sized.Vector n Int`, and we have
+--                     `'KnownNat' n`
+-- @
+--
+-- The @n@ type variable will be properly instantiated to whatever the
+-- length of the vector is, and you will also have a @'KnownNat' n@
+-- instance available.  You can get @n@ in scope by turning on
+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector
+-- n Int)@.
+--
+-- Without this, you would otherwise have to use 'withSized' to do the same
+-- thing:
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc u = 'withSized' u $ \\v ->
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+-- @
+--
+-- Remember that the type of final result of your function (the @Int@,
+-- here) must /not/ depend on @n@.  However, the types of the intermediate
+-- values are allowed to depend on @n@.
+--
+-- This is /especially/ useful in do blocks, where you can pattern match on
+-- the unsized results of actions, to use the sized vector in the rest of
+-- the do block.  You also get a @'KnownNat' n@ constraint for the
+-- remainder of the do block.
+--
+-- @
+-- -- If you had:
+-- getAVector :: IO (Unsized.Vector Int)
+--
+-- main :: IO ()
+-- main = do
+--     SomeSized v <- getAVector -- v is `Sized.Vector n Int`
+--     -- get n in scope
+--     SomeSized (v :: Sized.Vector n Int) <- getAVector
+--     print v
+-- @
+--
+-- Remember that the final type of the result of the do block ('()', here)
+-- must not depend on @n@.  However, the 
+--
+-- Also useful in ghci, where you can pattern match to get sized vectors
+-- from unsized vectors.
+--
+-- @
+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)
+--              -- ^ v is `Sized.Vector n Int`
+-- @
+--
+-- This enables interactive exploration with sized vectors in ghci, and is
+-- useful for using with other libraries and functions that expect sized
+-- vectors in an interactive setting.
+--
+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci
+-- session using ScopedTypeVariables, like you can with do blocks)
+--
+-- You can also use this as a constructor, to take a sized vector and
+-- "hide" the size, to produce an unsized vector:
+--
+-- @
+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a
+-- @
+pattern SomeSized :: Storable a => KnownNat n => Vector n a -> VS.Vector a
+pattern SomeSized v = V.SomeSized v
+{-# complete SomeSized #-}
diff --git a/src/Data/Vector/Unboxed/Mutable/Sized.hs b/src/Data/Vector/Unboxed/Mutable/Sized.hs
--- a/src/Data/Vector/Unboxed/Mutable/Sized.hs
+++ b/src/Data/Vector/Unboxed/Mutable/Sized.hs
@@ -6,12 +6,12 @@
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Mutable.Sized'
- specialized to 'Data.Vector.Unboxed.Mutable'
+ specialized to 'Data.Vector.Unboxed.Mutable'.
 
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
@@ -94,7 +94,7 @@
 
 
 -- | 'Data.Vector.Generic.Mutable.Sized.Vector' specialized to use
--- 'Data.Vector.Unbox.Mutable'
+-- 'Data.Vector.Unbox.Mutable'.
 type MVector = VGM.MVector VSM.MVector
 
 -- * Accessors
@@ -113,7 +113,7 @@
 length' = VGM.length'
 {-# inline length' #-}
 
--- | /O(1)/ Check whether the mutable vector is empty
+-- | /O(1)/ Check whether the mutable vector is empty.
 null :: forall n s a. (KnownNat n)
        => MVector n s a -> Bool
 null = VGM.null
@@ -155,47 +155,47 @@
 tail = VGM.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n k s a. (KnownNat n, Unbox a)
      => MVector (n+k) s a -> MVector n s a
 take = VGM.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n k s a p. (KnownNat n, Unbox a)
       => p n -> MVector (n+k) s a -> MVector n s a
 take' = VGM.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n k s a. (KnownNat n, Unbox a)
      => MVector (n+k) s a -> MVector k s a
 drop = VGM.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall n k s a p. (KnownNat n, Unbox a)
       => p n -> MVector (n+k) s a -> MVector k s a
 drop' = VGM.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vectors are inferred from the type.
 splitAt :: forall n m s a. (KnownNat n, Unbox a)
         => MVector (n+m) s a -> (MVector n s a, MVector m s a)
 splitAt = VGM.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m s a p. (KnownNat n, Unbox a)
          => p n -> MVector (n+m) s a -> (MVector n s a, MVector m s a)
@@ -204,9 +204,7 @@
 
 -- ** Overlaps
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
--- inferred from the type.
+-- | /O(1)/ Check if two vectors overlap. 
 overlaps :: forall n k s a. Unbox a
          => MVector n s a
          -> MVector k s a
@@ -349,13 +347,13 @@
 unsafeModify = VGM.unsafeModify
 {-# inline unsafeModify #-}
 
--- | /O(1)/ Swap the elements at a given type-safe position using 'Finite's.
+-- | /O(1)/ Swap the elements at the given type-safe positions using 'Finite's.
 swap :: forall n m a. (PrimMonad m, Unbox a)
      => MVector n (PrimState m) a -> Finite n -> Finite n -> m ()
 swap = VGM.swap
 {-# inline swap #-}
 
--- | /O(1)/ Swap the elements at a given 'Int' position without bounds
+-- | /O(1)/ Swap the elements at the given 'Int' positions without bounds
 -- checking.
 unsafeSwap :: forall n m a. (PrimMonad m, Unbox a)
            => MVector n (PrimState m) a -> Int -> Int -> m ()
@@ -386,7 +384,7 @@
 #if MIN_VERSION_vector(0,12,0)
 -- * Modifying vectors
 
--- | Compute the next (lexicographically) permutation of a given vector
+-- | Compute the next permutation (lexicographically) of a given vector
 -- in-place.  Returns 'False' when the input is the last permutation.
 nextPermutation :: forall n e m. (Ord e, PrimMonad m, Unbox e)
                 => MVector n (PrimState m) e -> m Bool
diff --git a/src/Data/Vector/Unboxed/Sized.hs b/src/Data/Vector/Unboxed/Sized.hs
--- a/src/Data/Vector/Unboxed/Sized.hs
+++ b/src/Data/Vector/Unboxed/Sized.hs
@@ -5,6 +5,7 @@
 {-# LANGUAGE RankNTypes          #-}
 {-# LANGUAGE ScopedTypeVariables #-}
 {-# LANGUAGE TypeOperators       #-}
+{-# LANGUAGE PatternSynonyms    #-}
 {-# LANGUAGE CPP                 #-}
 
 #if MIN_VERSION_base(4,12,0)
@@ -13,17 +14,18 @@
 
 {-|
 This module re-exports the functionality in 'Data.Vector.Generic.Sized'
- specialized to 'Data.Vector.Unboxed'
+ specialized to 'Data.Vector.Unboxed'.
 
 Functions returning a vector determine the size from the type context unless
 they have a @'@ suffix in which case they take an explicit 'Proxy' argument.
 
-Functions where the resultant vector size is not know until compile time are
+Functions where the resulting vector size is not known until runtime are
 not exported.
 -}
 
 module Data.Vector.Unboxed.Sized
  ( Vector
+  , pattern SomeSized
   , VUM.MVector
    -- * Accessors
    -- ** Length information
@@ -263,7 +265,7 @@
                         showsPrec )
 
 -- | 'Data.Vector.Generic.Sized.Vector' specialized to use
--- 'Data.Vector.Unboxed'
+-- 'Data.Vector.Unboxed'.
 type Vector = V.Vector VU.Vector
 
 -- | /O(1)/ Yield the length of the vector as an 'Int'. This is more like
@@ -310,7 +312,7 @@
 index' = V.index'
 {-# inline index' #-}
 
--- | /O(1)/ Indexing using an Int without bounds checking.
+-- | /O(1)/ Indexing using an 'Int' without bounds checking.
 unsafeIndex :: forall n a. Unbox a
       => Vector n a -> Int -> a
 unsafeIndex = V.unsafeIndex
@@ -346,8 +348,7 @@
 _last = V._last
 {-# inline _last #-}
 
-
--- | /O(1)/ Safe indexing in a monad. See the documentation for 'VG.indexM' for
+-- | /O(1)/ Safe indexing in a monad. See the documentation for 'Data.Vector.Generic.Sized.indexM' for
 -- an explanation of why this is useful.
 indexM :: forall n a m. (Unbox a, Monad m)
       => Vector n a -> Finite n -> m a
@@ -355,28 +356,28 @@
 {-# inline indexM #-}
 
 -- | /O(1)/ Safe indexing in a monad using a 'Proxy'. See the documentation for
--- 'VG.indexM' for an explanation of why this is useful.
+-- 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 indexM' :: forall n k a m p. (KnownNat n, Unbox a, Monad m)
       => Vector (n+k) a -> p n -> m a
 indexM' = V.indexM'
 {-# inline indexM' #-}
 
 -- | /O(1)/ Indexing using an Int without bounds checking. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 unsafeIndexM :: forall n a m. (Unbox a, Monad m)
       => Vector n a -> Int -> m a
 unsafeIndexM = V.unsafeIndexM
 {-# inline unsafeIndexM #-}
 
 -- | /O(1)/ Yield the first element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 headM :: forall n a m. (Unbox a, Monad m)
       => Vector (1+n) a -> m a
 headM = V.headM
 {-# inline headM #-}
 
 -- | /O(1)/ Yield the last element of a non-empty vector in a monad. See the
--- documentation for 'VG.indexM' for an explanation of why this is useful.
+-- documentation for 'Data.Vector.Generic.Sized.indexM' for an explanation of why this is useful.
 lastM :: forall n a m. (Unbox a, Monad m)
       => Vector (n+1) a -> m a
 lastM = V.lastM
@@ -415,47 +416,47 @@
 tail = V.tail
 {-# inline tail #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is inferred from the
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is inferred from the
 -- type.
 take :: forall n m a. (KnownNat n, Unbox a)
      => Vector (n+m) a -> Vector n a
 take = V.take
 {-# inline take #-}
 
--- | /O(1)/ Yield the first n elements. The resultant vector always contains
--- this many elements. The length of the resultant vector is given explicitly
+-- | /O(1)/ Yield the first @n@ elements. The resulting vector always contains
+-- this many elements. The length of the resulting vector is given explicitly
 -- as a 'Proxy' argument.
 take' :: forall n m a p. (KnownNat n, Unbox a)
       => p n -> Vector (n+m) a -> Vector n a
 take' = V.take'
 {-# inline take' #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- inferred from the type.
 drop :: forall n m a. (KnownNat n, Unbox a)
      => Vector (n+m) a -> Vector m a
 drop = V.drop
 {-# inline drop #-}
 
--- | /O(1)/ Yield all but the the first n elements. The given vector must
--- contain at least this many elements The length of the resultant vector is
+-- | /O(1)/ Yield all but the the first @n@ elements. The given vector must
+-- contain at least this many elements. The length of the resulting vector is
 -- givel explicitly as a 'Proxy' argument.
 drop' :: forall n m a p. (KnownNat n, Unbox a)
       => p n -> Vector (n+m) a -> Vector m a
 drop' = V.drop'
 {-# inline drop' #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without copying.
--- The lengths of the resultant vector are inferred from the type.
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without copying.
+-- The lengths of the resulting vector are inferred from the type.
 splitAt :: forall n m a. (KnownNat n, Unbox a)
         => Vector (n+m) a -> (Vector n a, Vector m a)
 splitAt = V.splitAt
 {-# inline splitAt #-}
 
--- | /O(1)/ Yield the first n elements paired with the remainder without
--- copying.  The length of the first resultant vector is passed explicitly as a
+-- | /O(1)/ Yield the first @n@ elements, paired with the rest, without
+-- copying.  The length of the first resulting vector is passed explicitly as a
 -- 'Proxy' argument.
 splitAt' :: forall n m a p. (KnownNat n, Unbox a)
          => p n -> Vector (n+m) a -> (Vector n a, Vector m a)
@@ -483,8 +484,10 @@
 {-# inline singleton #-}
 
 -- | /O(n)/ Construct a vector in a type safe manner
+-- @
 --   fromTuple (1,2) :: Vector 2 Int
 --   fromTuple ("hey", "what's", "going", "on") :: Vector 4 String
+-- @
 fromTuple :: forall a input length.
              (Unbox a, IndexedListLiterals input length a, KnownNat length)
           => input -> Vector length a
@@ -519,14 +522,14 @@
 generate' = V.generate'
 {-# inline generate' #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is original value.
 -- The length is inferred from the type.
 iterateN :: forall n a. (KnownNat n, Unbox a)
          => (a -> a) -> a -> Vector n a
 iterateN = V.iterateN
 {-# inline iterateN #-}
 
--- | /O(n)/ Apply function n times to value. Zeroth element is original value.
+-- | /O(n)/ Apply the function @n@ times to a value. Zeroth element is original value.
 -- The length is given explicitly as a 'Proxy' argument.
 iterateN' :: forall n a p. (KnownNat n, Unbox a)
           => p n -> (a -> a) -> a -> Vector n a
@@ -552,14 +555,14 @@
 {-# inline replicateM' #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is inferred from the type.
+-- each index where @n@ is inferred from the type.
 generateM :: forall n m a. (KnownNat n, Unbox a, Monad m)
           => (Finite n -> m a) -> m (Vector n a)
 generateM = V.generateM
 {-# inline generateM #-}
 
 -- | /O(n)/ Construct a vector of length @n@ by applying the monadic action to
--- each index where n is given explicitly as a 'Proxy' argument.
+-- each index where @n@ is given explicitly as a 'Proxy' argument.
 generateM' :: forall n m a p. (KnownNat n, Unbox a, Monad m)
            => p n -> (Finite n -> m a) -> m (Vector n a)
 generateM' = V.generateM'
@@ -570,7 +573,7 @@
 --
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is inferred from the
+-- the generator function to the a seed. The length is inferred from the
 -- type.
 unfoldrN :: forall n a b. (KnownNat n, Unbox a)
          => (b -> (a, b)) -> b -> Vector n a
@@ -578,7 +581,7 @@
 {-# inline unfoldrN #-}
 
 -- | /O(n)/ Construct a vector with exactly @n@ elements by repeatedly applying
--- the generator function to the a seed. The length, @n@, is given explicitly
+-- the generator function to the a seed. The length is given explicitly
 -- as a 'Proxy' argument.
 unfoldrN' :: forall n a b p. (KnownNat n, Unbox a)
           => p n -> (b -> (a, b)) -> b -> Vector n a
@@ -589,29 +592,29 @@
 -- ** Enumeration
 --
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is inferred from the type.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is inferred from the type.
 enumFromN :: forall n a. (KnownNat n, Unbox a, Num a)
           => a -> Vector n a
 enumFromN = V.enumFromN
 {-# inline enumFromN #-}
 
--- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@
--- etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- | /O(n)/ Yield a vector of length @n@ containing the values @x@, @x+1@, ...,
+-- @x + (n - 1)@. The length is given explicitly as a 'Proxy' argument.
 enumFromN' :: forall n a p. (KnownNat n, Unbox a, Num a)
            => a -> p n -> Vector n a
 enumFromN' = V.enumFromN'
 {-# inline enumFromN' #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is inferred from the type.
+-- @x+2y@, ..., @x + (n - 1)y@. The length is inferred from the type.
 enumFromStepN :: forall n a. (KnownNat n, Unbox a, Num a)
           => a -> a -> Vector n a
 enumFromStepN = V.enumFromStepN
 {-# inline enumFromStepN #-}
 
 -- | /O(n)/ Yield a vector of the given length containing the values @x@, @x+y@,
--- @x+y+y@ etc. The length, @n@, is given explicitly as a 'Proxy' argument.
+-- @x+2y@, ..., @x + (n - 1)y@. The length is given explicitly as a 'Proxy' argument.
 enumFromStepN' :: forall n a p. (KnownNat n, Unbox a, Num a)
                => a -> a -> p n -> Vector n a
 enumFromStepN' = V.enumFromStepN'
@@ -817,7 +820,7 @@
 -- ** Permutations
 --
 
--- | /O(n)/ Reverse a vector
+-- | /O(n)/ Reverse a vector.
 reverse :: (Unbox a) => Vector n a -> Vector n a
 reverse = V.reverse
 {-# inline reverse #-}
@@ -850,7 +853,7 @@
 -- ** Indexing
 --
 
--- | /O(n)/ Pair each element in a vector with its index
+-- | /O(n)/ Pair each element in a vector with its index.
 indexed :: (Unbox a, Unbox (Finite n))
         => Vector n a -> Vector n (Finite n,a)
 indexed = V.indexed
@@ -860,13 +863,13 @@
 -- ** Mapping
 --
 
--- | /O(n)/ Map a function over a vector
+-- | /O(n)/ Map a function over a vector.
 map :: (Unbox a, Unbox b)
     => (a -> b) -> Vector n a -> Vector n b
 map = V.map
 {-# inline map #-}
 
--- | /O(n)/ Apply a function to every element of a vector and its index
+-- | /O(n)/ Apply a function to every element of a vector and its index.
 imap :: (Unbox a, Unbox b)
      => (Finite n -> a -> b) -> Vector n a -> Vector n b
 imap = V.imap
@@ -884,27 +887,27 @@
 --
 
 -- | /O(n)/ Apply the monadic action to all elements of the vector, yielding a
--- vector of results
+-- vector of results.
 mapM :: (Monad m, Unbox a, Unbox b)
       => (a -> m b) -> Vector n a -> m (Vector n b)
 mapM = V.mapM
 {-# inline mapM #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, yielding a vector of results
+-- index, yielding a vector of results.
 imapM :: (Monad m, Unbox a, Unbox b)
       => (Finite n -> a -> m b) -> Vector n a -> m (Vector n b)
 imapM = V.imapM
 {-# inline imapM #-}
 
 -- | /O(n)/ Apply the monadic action to all elements of a vector and ignore the
--- results
+-- results.
 mapM_ :: (Monad m, Unbox a) => (a -> m b) -> Vector n a -> m ()
 mapM_ = V.mapM_
 {-# inline mapM_ #-}
 
 -- | /O(n)/ Apply the monadic action to every element of a vector and its
--- index, ignoring the results
+-- index, ignoring the results.
 imapM_ :: (Monad m, Unbox a) => (Finite n -> a -> m b) -> Vector n a -> m ()
 imapM_ = V.imapM_
 {-# inline imapM_ #-}
@@ -1023,7 +1026,7 @@
 izipWith6 = V.izipWith6
 {-# inline izipWith6 #-}
 
--- | /O(n)/ Zip two vectors of the same length
+-- | /O(n)/ Zip two vectors of the same length.
 zip :: (Unbox a, Unbox b)
     => Vector n a -> Vector n b -> Vector n (a, b)
 zip = V.zip
@@ -1069,27 +1072,27 @@
 --
 
 -- | /O(n)/ Zip the two vectors of the same length with the monadic action and
--- yield a vector of results
+-- yield a vector of results.
 zipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)
          => (a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 zipWithM = V.zipWithM
 {-# inline zipWithM #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes the
--- element index and yield a vector of results
+-- element index and yield a vector of results.
 izipWithM :: (Monad m, Unbox a, Unbox b, Unbox c)
          => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m (Vector n c)
 izipWithM = V.izipWithM
 {-# inline izipWithM #-}
 
--- | /O(n)/ Zip the two vectors with the monadic action and ignore the results
+-- | /O(n)/ Zip the two vectors with the monadic action and ignore the results.
 zipWithM_ :: (Monad m, Unbox a, Unbox b)
           => (a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 zipWithM_ = V.zipWithM_
 {-# inline zipWithM_ #-}
 
 -- | /O(n)/ Zip the two vectors with a monadic action that also takes
--- the element index and ignore the results
+-- the element index and ignore the results.
 izipWithM_ :: (Monad m, Unbox a, Unbox b)
            => (Finite n -> a -> b -> m c) -> Vector n a -> Vector n b -> m ()
 izipWithM_ = V.izipWithM_
@@ -1134,13 +1137,13 @@
 
 
 infix 4 `elem`
--- | /O(n)/ Check if the vector contains an element
+-- | /O(n)/ Check if the vector contains an element.
 elem :: (Unbox a, Eq a) => a -> Vector n a -> Bool
 elem = V.elem
 {-# inline elem #-}
 
 infix 4 `notElem`
--- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem')
+-- | /O(n)/ Check if the vector does not contain an element (inverse of 'elem').
 notElem :: (Unbox a, Eq a) => a -> Vector n a -> Bool
 notElem = V.notElem
 {-# inline notElem #-}
@@ -1168,64 +1171,64 @@
 -- * Folding
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Left fold
+-- | /O(n)/ Left fold.
 foldl :: Unbox b => (a -> b -> a) -> a -> Vector n b -> a
 foldl = V.foldl
 {-# inline foldl #-}
 
--- | /O(n)/ Left fold on non-empty vectors
+-- | /O(n)/ Left fold on non-empty vectors.
 foldl1 :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1 = V.foldl1
 {-# inline foldl1 #-}
 
--- | /O(n)/ Left fold with strict accumulator
+-- | /O(n)/ Left fold with strict accumulator.
 foldl' :: Unbox b => (a -> b -> a) -> a -> Vector n b -> a
 foldl' = V.foldl'
 {-# inline foldl' #-}
 
--- | /O(n)/ Left fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Left fold on non-empty vectors with strict accumulator.
 foldl1' :: Unbox a => (a -> a -> a) -> Vector (1+n) a -> a
 foldl1' = V.foldl1'
 {-# inline foldl1' #-}
 
--- | /O(n)/ Right fold
+-- | /O(n)/ Right fold.
 foldr :: Unbox a => (a -> b -> b) -> b -> Vector n a -> b
 foldr = V.foldr
 {-# inline foldr #-}
 
--- | /O(n)/ Right fold on non-empty vectors
+-- | /O(n)/ Right fold on non-empty vectors.
 foldr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> a
 foldr1 = V.foldr1
 {-# inline foldr1 #-}
 
--- | /O(n)/ Right fold with a strict accumulator
+-- | /O(n)/ Right fold with a strict accumulator.
 foldr' :: Unbox a => (a -> b -> b) -> b -> Vector n a -> b
 foldr' = V.foldr'
 {-# inline foldr' #-}
 
--- | /O(n)/ Right fold on non-empty vectors with strict accumulator
+-- | /O(n)/ Right fold on non-empty vectors with strict accumulator.
 foldr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> a
 foldr1' = V.foldr1'
 {-# inline foldr1' #-}
 
--- | /O(n)/ Left fold (function applied to each element and its index)
+-- | /O(n)/ Left fold (function applied to each element and its index).
 ifoldl :: Unbox b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl = V.ifoldl
 {-# inline ifoldl #-}
 
 -- | /O(n)/ Left fold with strict accumulator (function applied to each element
--- and its index)
+-- and its index).
 ifoldl' :: Unbox b => (a -> Finite n -> b -> a) -> a -> Vector n b -> a
 ifoldl' = V.ifoldl'
 {-# inline ifoldl' #-}
 
--- | /O(n)/ Right fold (function applied to each element and its index)
+-- | /O(n)/ Right fold (function applied to each element and its index).
 ifoldr :: Unbox a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr = V.ifoldr
 {-# inline ifoldr #-}
 
 -- | /O(n)/ Right fold with strict accumulator (function applied to each
--- element and its index)
+-- element and its index).
 ifoldr' :: Unbox a => (Finite n -> a -> b -> b) -> b -> Vector n a -> b
 ifoldr' = V.ifoldr'
 {-# inline ifoldr' #-}
@@ -1242,22 +1245,22 @@
 any = V.any
 {-# inline any #-}
 
--- | /O(n)/ Check if all elements are 'True'
+-- | /O(n)/ Check if all elements are 'True'.
 and :: Vector n Bool -> Bool
 and = V.and
 {-# inline and #-}
 
--- | /O(n)/ Check if any element is 'True'
+-- | /O(n)/ Check if any element is 'True'.
 or :: Vector n Bool -> Bool
 or = V.or
 {-# inline or #-}
 
--- | /O(n)/ Compute the sum of the elements
+-- | /O(n)/ Compute the sum of the elements.
 sum :: (Unbox a, Num a) => Vector n a -> a
 sum = V.sum
 {-# inline sum #-}
 
--- | /O(n)/ Compute the produce of the elements
+-- | /O(n)/ Compute the product of the elements.
 product :: (Unbox a, Num a) => Vector n a -> a
 product = V.product
 {-# inline product #-}
@@ -1312,74 +1315,74 @@
 
 -- ** Monadic folds
 
--- | /O(n)/ Monadic fold
+-- | /O(n)/ Monadic fold.
 foldM :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM = V.foldM
 {-# inline foldM #-}
 
--- | /O(n)/ Monadic fold (action applied to each element and its index)
+-- | /O(n)/ Monadic fold (action applied to each element and its index).
 ifoldM :: (Monad m, Unbox b) => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM = V.ifoldM
 {-# inline ifoldM #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors
+-- | /O(n)/ Monadic fold over non-empty vectors.
 fold1M :: (Monad m, Unbox a)
        => (a -> a -> m a) -> Vector (1+n) a -> m a
 fold1M = V.fold1M
 {-# inline fold1M #-}
 
--- | /O(n)/ Monadic fold with strict accumulator
+-- | /O(n)/ Monadic fold with strict accumulator.
 foldM' :: (Monad m, Unbox b) => (a -> b -> m a) -> a -> Vector n b -> m a
 foldM' = V.foldM'
 {-# inline foldM' #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator (action applied to each
--- element and its index)
+-- element and its index).
 ifoldM' :: (Monad m, Unbox b)
         => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m a
 ifoldM' = V.ifoldM'
 {-# inline ifoldM' #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator
+-- | /O(n)/ Monadic fold over non-empty vectors with strict accumulator.
 fold1M' :: (Monad m, Unbox a)
         => (a -> a -> m a) -> Vector (n+1) a -> m a
 fold1M' = V.fold1M'
 {-# inline fold1M' #-}
 
--- | /O(n)/ Monadic fold that discards the result
+-- | /O(n)/ Monadic fold that discards the result.
 foldM_ :: (Monad m, Unbox b)
        => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM_ = V.foldM_
 {-# inline foldM_ #-}
 
 -- | /O(n)/ Monadic fold that discards the result (action applied to
--- each element and its index)
+-- each element and its index).
 ifoldM_ :: (Monad m, Unbox b)
         => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM_ = V.ifoldM_
 {-# inline ifoldM_ #-}
 
--- | /O(n)/ Monadic fold over non-empty vectors that discards the result
+-- | /O(n)/ Monadic fold over non-empty vectors that discards the result.
 fold1M_ :: (Monad m, Unbox a)
         => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M_ = V.fold1M_
 {-# inline fold1M_ #-}
 
--- | /O(n)/ Monadic fold with strict accumulator that discards the result
+-- | /O(n)/ Monadic fold with strict accumulator that discards the result.
 foldM'_ :: (Monad m, Unbox b)
         => (a -> b -> m a) -> a -> Vector n b -> m ()
 foldM'_ = V.foldM'_
 {-# inline foldM'_ #-}
 
 -- | /O(n)/ Monadic fold with strict accumulator that discards the result
--- (action applied to each element and its index)
+-- (action applied to each element and its index).
 ifoldM'_ :: (Monad m, Unbox b)
          => (a -> Finite n -> b -> m a) -> a -> Vector n b -> m ()
 ifoldM'_ = V.ifoldM'_
 {-# inline ifoldM'_ #-}
 
 -- | /O(n)/ Monad fold over non-empty vectors with strict accumulator
--- that discards the result
+-- that discards the result.
 fold1M'_ :: (Monad m, Unbox a)
          => (a -> a -> m a) -> Vector (n+1) a -> m ()
 fold1M'_ = V.fold1M'_
@@ -1387,13 +1390,13 @@
 
 -- ** Monadic sequencing
 
--- | Evaluate each action and collect the results
+-- | Evaluate each action and collect the results.
 sequence :: (Monad m, Unbox a, Unbox (m a))
          => Vector n (m a) -> m (Vector n a)
 sequence = V.sequence
 {-# inline sequence #-}
 
--- | Evaluate each action and discard the results
+-- | Evaluate each action and discard the results.
 sequence_ :: (Monad m, Unbox (m a)) => Vector n (m a) -> m ()
 sequence_ = V.sequence_
 {-# inline sequence_ #-}
@@ -1402,7 +1405,7 @@
 -- * Prefix sums (scans)
 --------------------------------------------------------------------------------
 
--- | /O(n)/ Prescan
+-- | /O(n)/ Prescan.
 --
 -- @
 -- prescanl f z = 'init' . 'scanl' f z
@@ -1414,78 +1417,78 @@
 prescanl = V.prescanl
 {-# inline prescanl #-}
 
--- | /O(n)/ Prescan with strict accumulator
+-- | /O(n)/ Prescan with strict accumulator.
 prescanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 prescanl' = V.prescanl'
 {-# inline prescanl' #-}
 
--- | /O(n)/ Scan
+-- | /O(n)/ Scan.
 postscanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl = V.postscanl
 {-# inline postscanl #-}
 
--- | /O(n)/ Scan with strict accumulator
+-- | /O(n)/ Scan with strict accumulator.
 postscanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 postscanl' = V.postscanl'
 {-# inline postscanl' #-}
 
--- | /O(n)/ Haskell-style scan
+-- | /O(n)/ Haskell-style scan.
 scanl :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl = V.scanl
 {-# inline scanl #-}
 
--- | /O(n)/ Haskell-style scan with strict accumulator
+-- | /O(n)/ Haskell-style scan with strict accumulator.
 scanl' :: (Unbox a, Unbox b) => (a -> b -> a) -> a -> Vector n b -> Vector n a
 scanl' = V.scanl'
 {-# inline scanl' #-}
 
--- | /O(n)/ Scan over a non-empty vector
+-- | /O(n)/ Scan over a non-empty vector.
 scanl1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1 = V.scanl1
 {-# inline scanl1 #-}
 
--- | /O(n)/ Scan over a non-empty vector with a strict accumulator
+-- | /O(n)/ Scan over a non-empty vector with a strict accumulator.
 scanl1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanl1' = V.scanl1'
 {-# inline scanl1' #-}
 
--- | /O(n)/ Right-to-left prescan
+-- | /O(n)/ Right-to-left prescan.
 prescanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr = V.prescanr
 {-# inline prescanr #-}
 
--- | /O(n)/ Right-to-left prescan with strict accumulator
+-- | /O(n)/ Right-to-left prescan with strict accumulator.
 prescanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 prescanr' = V.prescanr'
 {-# inline prescanr' #-}
 
--- | /O(n)/ Right-to-left scan
+-- | /O(n)/ Right-to-left scan.
 postscanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr = V.postscanr
 {-# inline postscanr #-}
 
--- | /O(n)/ Right-to-left scan with strict accumulator
+-- | /O(n)/ Right-to-left scan with strict accumulator.
 postscanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 postscanr' = V.postscanr'
 {-# inline postscanr' #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan
+-- | /O(n)/ Right-to-left Haskell-style scan.
 scanr :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr = V.scanr
 {-# inline scanr #-}
 
--- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator
+-- | /O(n)/ Right-to-left Haskell-style scan with strict accumulator.
 scanr' :: (Unbox a, Unbox b) => (a -> b -> b) -> b -> Vector n a -> Vector n b
 scanr' = V.scanr'
 {-# inline scanr' #-}
 
--- | /O(n)/ Right-to-left scan over a non-empty vector
+-- | /O(n)/ Right-to-left scan over a non-empty vector.
 scanr1 :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1 = V.scanr1
 {-# inline scanr1 #-}
 
 -- | /O(n)/ Right-to-left scan over a non-empty vector with a strict
--- accumulator
+-- accumulator.
 scanr1' :: Unbox a => (a -> a -> a) -> Vector (n+1) a -> Vector (n+1) a
 scanr1' = V.scanr1'
 {-# inline scanr1' #-}
@@ -1495,25 +1498,25 @@
 
 -- ** Lists
 
--- | /O(n)/ Convert a vector to a list
+-- | /O(n)/ Convert a vector to a list.
 toList :: Unbox a => Vector n a -> [a]
 toList = V.toList
 {-# inline toList #-}
 
--- | /O(n)/ Convert a list to a vector
+-- | /O(n)/ Convert a list to a vector.
 fromList :: (Unbox a, KnownNat n) => [a] -> Maybe (Vector n a)
 fromList = V.fromList
 {-# inline fromList #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is inferred from the type.
+-- the resulting vector is inferred from the type.
 fromListN :: forall n a. (Unbox a, KnownNat n)
           => [a] -> Maybe (Vector n a)
 fromListN = V.fromListN
 {-# inline fromListN #-}
 
 -- | /O(n)/ Convert the first @n@ elements of a list to a vector. The length of
--- the resultant vector is given explicitly as a 'Proxy' argument.
+-- the resulting vector is given explicitly as a 'Proxy' argument.
 fromListN' :: forall n a p. (Unbox a, KnownNat n)
            => p n -> [a] -> Maybe (Vector n a)
 fromListN' = V.fromListN'
@@ -1570,7 +1573,7 @@
 
 -- | Convert a 'Data.Vector.Generic.Vector' into a
 -- 'Data.Vector.Generic.Sized.Vector' if it has the correct size, otherwise
--- return Nothing.
+-- return 'Nothing'.
 toSized :: forall n a. (Unbox a, KnownNat n)
         => VU.Vector a -> Maybe (Vector n a)
 toSized = V.toSized
@@ -1600,3 +1603,78 @@
 withVectorUnsafe = V.withVectorUnsafe
 {-# inline withVectorUnsafe #-}
 
+-- | Pattern synonym that lets you treat an unsized vector as if it
+-- "contained" a sized vector.  If you pattern match on an unsized vector,
+-- its contents will be the /sized/ vector counterpart.
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc ('SomeSized' v) =
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+--         -- ^ here, v is `Sized.Vector n Int`, and we have
+--                     `'KnownNat' n`
+-- @
+--
+-- The @n@ type variable will be properly instantiated to whatever the
+-- length of the vector is, and you will also have a @'KnownNat' n@
+-- instance available.  You can get @n@ in scope by turning on
+-- ScopedTypeVariables and matching on @'SomeSized' (v :: Sized.Vector
+-- n Int)@.
+--
+-- Without this, you would otherwise have to use 'withSized' to do the same
+-- thing:
+--
+-- @
+-- testFunc :: Unsized.Vector Int -> Int
+-- testFunc u = 'withSized' u $ \\v ->
+--     'sum' ('zipWith' (+) v ('replicate' 1))
+-- @
+--
+-- Remember that the type of final result of your function (the @Int@,
+-- here) must /not/ depend on @n@.  However, the types of the intermediate
+-- values are allowed to depend on @n@.
+--
+-- This is /especially/ useful in do blocks, where you can pattern match on
+-- the unsized results of actions, to use the sized vector in the rest of
+-- the do block.  You also get a @'KnownNat' n@ constraint for the
+-- remainder of the do block.
+--
+-- @
+-- -- If you had:
+-- getAVector :: IO (Unsized.Vector Int)
+--
+-- main :: IO ()
+-- main = do
+--     SomeSized v <- getAVector -- v is `Sized.Vector n Int`
+--     -- get n in scope
+--     SomeSized (v :: Sized.Vector n Int) <- getAVector
+--     print v
+-- @
+--
+-- Remember that the final type of the result of the do block ('()', here)
+-- must not depend on @n@.  However, the 
+--
+-- Also useful in ghci, where you can pattern match to get sized vectors
+-- from unsized vectors.
+--
+-- @
+-- ghci> SomeSized v <- pure (myUnsizedVector :: Unsized.Vector Int)
+--              -- ^ v is `Sized.Vector n Int`
+-- @
+--
+-- This enables interactive exploration with sized vectors in ghci, and is
+-- useful for using with other libraries and functions that expect sized
+-- vectors in an interactive setting.
+--
+-- (Note that as of GHC 8.6, you cannot get the @n@ in scope in your ghci
+-- session using ScopedTypeVariables, like you can with do blocks)
+--
+-- You can also use this as a constructor, to take a sized vector and
+-- "hide" the size, to produce an unsized vector:
+--
+-- @
+-- SomeSized :: Sized.Vector n a -> Unsized.Vector a
+-- @
+pattern SomeSized :: Unbox a => KnownNat n => Vector n a -> VU.Vector a
+pattern SomeSized v = V.SomeSized v
+{-# complete SomeSized #-}
diff --git a/vector-sized.cabal b/vector-sized.cabal
--- a/vector-sized.cabal
+++ b/vector-sized.cabal
@@ -1,5 +1,5 @@
 name:                vector-sized
-version:             1.1.1.0
+version:             1.2.0.0
 synopsis:            Size tagged vectors
 description:         Please see README.md
 homepage:            http://github.com/expipiplus1/vector-sized#readme
@@ -35,6 +35,7 @@
                      , adjunctions >= 4.3 && < 4.5
                      , distributive >= 0.5 && < 0.7
                      , comonad >=4 && <6
+                     , hashable >= 1.2.4.0 && < 1.3
   default-language:    Haskell2010
 
   -- if impl(ghc >= 8.6)
