diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,9 @@
+## 1.0.10.0
+
+* Make index work on negative indices
+  [#172](https://github.com/snoyberg/mono-traversable/issues/172)
+  [#114](https://github.com/snoyberg/mono-traversable/issues/114)
+
 ## 1.0.9.0
 
 * Added `filterMap` to `Data.Containers`
diff --git a/mono-traversable.cabal b/mono-traversable.cabal
--- a/mono-traversable.cabal
+++ b/mono-traversable.cabal
@@ -1,13 +1,13 @@
-cabal-version: >= 1.10
+cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.29.0.
+-- This file has been generated from package.yaml by hpack version 0.30.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: 6bcc1ed72e15c5adb841eb249f106e08f6823d8dfb67f86e62a140618a3b93c0
+-- hash: dd6993a12a11dc33b47bd2f3d81ac5ab62e3168ad8a01582458b74b64f971031
 
 name:           mono-traversable
-version:        1.0.9.0
+version:        1.0.10.0
 synopsis:       Type classes for mapping, folding, and traversing monomorphic containers
 description:    Please see the README at <https://www.stackage.org/package/mono-traversable>
 category:       Data
@@ -19,8 +19,8 @@
 license-file:   LICENSE
 build-type:     Simple
 extra-source-files:
-    ChangeLog.md
     README.md
+    ChangeLog.md
 
 source-repository head
   type: git
diff --git a/src/Data/MonoTraversable.hs b/src/Data/MonoTraversable.hs
--- a/src/Data/MonoTraversable.hs
+++ b/src/Data/MonoTraversable.hs
@@ -331,7 +331,7 @@
     -- Note: this is a partial function. On an empty 'MonoFoldable', it will
     -- throw an exception.
     --
-    -- /See 'Data.NonNull.ofoldr1Ex' from "Data.NonNull" for a total version of this function./
+    -- /See 'Data.NonNull.ofoldr1' from "Data.NonNull" for a total version of this function./
     ofoldr1Ex :: (Element mono -> Element mono -> Element mono) -> mono -> Element mono
     default ofoldr1Ex :: (t a ~ mono, a ~ Element (t a), F.Foldable t)
                       => (Element mono -> Element mono -> Element mono) -> mono -> Element mono
@@ -344,7 +344,7 @@
     -- Note: this is a partial function. On an empty 'MonoFoldable', it will
     -- throw an exception.
     --
-    -- /See 'Data.NonNull.ofoldl1Ex'' from "Data.NonNull" for a total version of this function./
+    -- /See 'Data.NonNull.ofoldl1'' from "Data.NonNull" for a total version of this function./
     ofoldl1Ex' :: (Element mono -> Element mono -> Element mono) -> mono -> Element mono
     default ofoldl1Ex' :: (t a ~ mono, a ~ Element (t a), F.Foldable t)
                        => (Element mono -> Element mono -> Element mono) -> mono -> Element mono
@@ -366,7 +366,7 @@
     -- Note: this is a partial function. On an empty 'MonoFoldable', it will
     -- throw an exception.
     --
-    -- /See 'Data.NonNull.last from "Data.NonNull" for a total version of this function./
+    -- /See 'Data.NonNull.last' from "Data.NonNull" for a total version of this function./
     lastEx :: mono -> Element mono
     lastEx = ofoldl1Ex' (flip const)
     {-# INLINE lastEx #-}
diff --git a/src/Data/NonNull.hs b/src/Data/NonNull.hs
--- a/src/Data/NonNull.hs
+++ b/src/Data/NonNull.hs
@@ -162,17 +162,17 @@
   fromMaybe (error "Data.NonNull.splitFirst: data structure is null, it should be non-null")
           $ uncons (toNullable xs)
 
--- | Equivalent to @"Data.Sequence".'Data.Sequence.filter'@,
+-- | Equivalent to @"Data.Sequences".'Data.Sequences.filter'@,
 -- but works on non-nullable sequences.
 nfilter :: IsSequence seq => (Element seq -> Bool) -> NonNull seq -> seq
 nfilter f = filter f . toNullable
 
--- | Equivalent to @"Data.Sequence".'Data.Sequence.filterM'@,
+-- | Equivalent to @"Data.Sequences".'Data.Sequences.filterM'@,
 -- but works on non-nullable sequences.
 nfilterM :: (Monad m, IsSequence seq) => (Element seq -> m Bool) -> NonNull seq -> m seq
 nfilterM f = filterM f . toNullable
 
--- | Equivalent to @"Data.Sequence".'Data.Sequence.replicate'@
+-- | Equivalent to @"Data.Sequences".'Data.Sequences.replicate'@
 --
 -- @i@ must be @> 0@
 --
diff --git a/src/Data/Sequences.hs b/src/Data/Sequences.hs
--- a/src/Data/Sequences.hs
+++ b/src/Data/Sequences.hs
@@ -15,7 +15,7 @@
 import qualified Data.List as List
 import qualified Data.List.Split as List
 import qualified Control.Monad (filterM, replicateM)
-import Prelude (Bool (..), Monad (..), Maybe (..), Ordering (..), Ord (..), Eq (..), Functor (..), fromIntegral, otherwise, (-), fst, snd, Integral, ($), flip, maybe, error)
+import Prelude (Bool (..), Monad (..), Maybe (..), Ordering (..), Ord (..), Eq (..), Functor (..), fromIntegral, otherwise, (-), fst, snd, Integral, ($), flip, maybe, error, (||))
 import Data.Char (Char, isSpace)
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Lazy as L
@@ -447,7 +447,9 @@
     -- 'Nothing'
     -- @
     index :: seq -> Index seq -> Maybe (Element seq)
-    index seq' idx = headMay (drop idx seq')
+    index seq' idx
+        | idx < 0 = Nothing
+        | otherwise = headMay (drop idx seq')
 
     -- | __Unsafe__
     --
@@ -702,8 +704,8 @@
     {-# INLINE splitWhen #-}
 
     index bs i
-        | i >= S.length bs = Nothing
-        | otherwise = Just (S.index bs i)
+        | i < 0 || i >= S.length bs = Nothing
+        | otherwise = Just (SU.unsafeIndex bs i)
     indexEx = S.index
     unsafeIndex = SU.unsafeIndex
     {-# INLINE index #-}
@@ -766,7 +768,7 @@
     {-# INLINE splitWhen #-}
 
     index t i
-        | i >= T.length t = Nothing
+        | i < 0 || i >= T.length t = Nothing
         | otherwise = Just (T.index t i)
     indexEx = T.index
     unsafeIndex = T.index
@@ -952,9 +954,7 @@
     {-# INLINE tailEx #-}
     {-# INLINE initEx #-}
 
-    index seq' i
-        | i >= Seq.length seq' = Nothing
-        | otherwise = Just (Seq.index seq' i)
+    index = (Seq.!?)
     indexEx = Seq.index
     unsafeIndex = Seq.index
     {-# INLINE index #-}
@@ -1027,9 +1027,7 @@
     {-# INLINE unsafeTail #-}
     {-# INLINE unsafeInit #-}
 
-    index v i
-        | i >= V.length v = Nothing
-        | otherwise = Just (v V.! i)
+    index = (V.!?)
     indexEx = (V.!)
     unsafeIndex = V.unsafeIndex
     {-# INLINE index #-}
@@ -1102,9 +1100,7 @@
     {-# INLINE unsafeTail #-}
     {-# INLINE unsafeInit #-}
 
-    index v i
-        | i >= U.length v = Nothing
-        | otherwise = Just (v U.! i)
+    index = (U.!?)
     indexEx = (U.!)
     unsafeIndex = U.unsafeIndex
     {-# INLINE index #-}
@@ -1177,9 +1173,7 @@
     {-# INLINE unsafeTail #-}
     {-# INLINE unsafeInit #-}
 
-    index v i
-        | i >= VS.length v = Nothing
-        | otherwise = Just (v VS.! i)
+    index = (VS.!?)
     indexEx = (VS.!)
     unsafeIndex = VS.unsafeIndex
     {-# INLINE index #-}
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -154,7 +154,7 @@
 
     describe "index" $ do
         let test name dummy = prop name $
-              \(NonNegative i') (QCM.NonEmpty xs) ->
+              \i' (QCM.NonEmpty xs) ->
                 let seq' = fromListAs xs dummy
                     mx   = index xs (fromIntegral i)
                     i    = fromIntegral (i' :: Int)
