diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,10 @@
 # ChangeLog for mono-traversable
 
+## 1.0.15.2
+
+* Support transformers 0.6.0.0 [#196](https://github.com/snoyberg/mono-traversable/issues/196)
+* Compile with GHC 9 [#193](https://github.com/snoyberg/mono-traversable/pull/193)
+
 ## 1.0.15.1
 
 * Remove whitespace after `@` in as-patterns for GHC HEAD [#186](https://github.com/snoyberg/mono-traversable/pull/186)
diff --git a/mono-traversable.cabal b/mono-traversable.cabal
--- a/mono-traversable.cabal
+++ b/mono-traversable.cabal
@@ -1,13 +1,11 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.2.
+-- This file has been generated from package.yaml by hpack version 0.34.4.
 --
 -- see: https://github.com/sol/hpack
---
--- hash: b2ac08c2845dd12213a3bc3c6e01f805bb98a7693a588b0ae313ceadcb5ca592
 
 name:           mono-traversable
-version:        1.0.15.1
+version:        1.0.15.2
 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
@@ -39,7 +37,7 @@
       src
   ghc-options: -Wall
   build-depends:
-      base >=4.10 && <5
+      base >=4.13 && <5
     , bytestring >=0.9
     , containers >=0.5.8
     , hashable
@@ -49,16 +47,12 @@
     , unordered-containers >=0.2
     , vector >=0.10
     , vector-algorithms >=0.6
-  if impl(ghc <8.0)
-    build-depends:
-        semigroups >=0.10
   default-language: Haskell2010
 
 test-suite test
   type: exitcode-stdio-1.0
-  main-is: main.hs
+  main-is: Main.hs
   other-modules:
-      Spec
       Paths_mono_traversable
   hs-source-dirs:
       test
@@ -72,7 +66,6 @@
     , foldl
     , hspec
     , mono-traversable
-    , semigroups
     , text
     , transformers
     , unordered-containers
diff --git a/src/Data/MonoTraversable.hs b/src/Data/MonoTraversable.hs
--- a/src/Data/MonoTraversable.hs
+++ b/src/Data/MonoTraversable.hs
@@ -72,7 +72,9 @@
 import Data.HashMap.Strict (HashMap)
 import Data.Vector (Vector)
 import Control.Monad.Trans.Maybe (MaybeT (..))
+#if !MIN_VERSION_transformers(0,6,0)
 import Control.Monad.Trans.List (ListT)
+#endif
 import Control.Monad.Trans.Writer (WriterT)
 import qualified Control.Monad.Trans.Writer.Strict as Strict (WriterT)
 import Control.Monad.Trans.State (StateT(..))
@@ -128,7 +130,9 @@
 type instance Element (Vector a) = a
 type instance Element (WrappedArrow a b c) = c
 type instance Element (MaybeT m a) = a
+#if !MIN_VERSION_transformers(0,6,0)
 type instance Element (ListT m a) = a
+#endif
 type instance Element (IdentityT m a) = a
 type instance Element (WriterT w m a) = a
 type instance Element (Strict.WriterT w m a) = a
@@ -198,7 +202,9 @@
 instance MonoFunctor (Arg a b)
 instance Arrow a => MonoFunctor (WrappedArrow a b c)
 instance Functor m => MonoFunctor (MaybeT m a)
+#if !MIN_VERSION_transformers(0,6,0)
 instance Functor m => MonoFunctor (ListT m a)
+#endif
 instance Functor m => MonoFunctor (IdentityT m a)
 instance Functor m => MonoFunctor (WriterT w m a)
 instance Functor m => MonoFunctor (Strict.WriterT w m a)
@@ -801,7 +807,9 @@
 instance MonoFoldable (a, b)
 instance MonoFoldable (Const m a)
 instance F.Foldable f => MonoFoldable (MaybeT f a)
+#if !MIN_VERSION_transformers(0,6,0)
 instance F.Foldable f => MonoFoldable (ListT f a)
+#endif
 instance F.Foldable f => MonoFoldable (IdentityT f a)
 instance F.Foldable f => MonoFoldable (WriterT w f a)
 instance F.Foldable f => MonoFoldable (Strict.WriterT w f a)
@@ -1099,7 +1107,9 @@
 instance MonoTraversable (a, b)
 instance MonoTraversable (Const m a)
 instance Traversable f => MonoTraversable (MaybeT f a)
+#if !MIN_VERSION_transformers(0,6,0)
 instance Traversable f => MonoTraversable (ListT f a)
+#endif
 instance Traversable f => MonoTraversable (IdentityT f a)
 instance Traversable f => MonoTraversable (WriterT w f a)
 instance Traversable f => MonoTraversable (Strict.WriterT w f a)
@@ -1209,7 +1219,9 @@
 instance Monoid a => MonoPointed (a, b)
 instance Monoid m => MonoPointed (Const m a)
 instance Monad m => MonoPointed (WrappedMonad m a)
+#if !MIN_VERSION_transformers(0,6,0)
 instance Applicative m => MonoPointed (ListT m a)
+#endif
 instance Applicative m => MonoPointed (IdentityT m a)
 instance Arrow a => MonoPointed (WrappedArrow a b c)
 instance (Monoid w, Applicative m) => MonoPointed (WriterT w m a)
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,502 @@
+{-# LANGUAGE GADTs #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE ViewPatterns #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE PatternSynonyms #-}
+
+module Main where
+
+import Data.MonoTraversable
+import Data.Containers
+import Data.Sequences
+import qualified Data.Sequence as Seq
+import qualified Data.NonNull as NN
+import Data.Monoid (mempty, mconcat)
+import Data.Maybe (fromMaybe)
+import qualified Data.List as List
+
+import Test.Hspec
+import Test.Hspec.QuickCheck
+import Test.HUnit ((@?=))
+import Test.QuickCheck hiding (NonEmptyList(..))
+import Test.QuickCheck.Function (pattern Fn)
+import qualified Test.QuickCheck.Modifiers as QCM
+
+import Data.Text (Text)
+import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
+import qualified Data.ByteString as S
+import qualified Data.ByteString.Lazy as L
+import qualified Data.Vector as V
+import qualified Data.Vector.Unboxed as U
+import qualified Data.Vector.Storable as VS
+import qualified Data.List.NonEmpty as NE
+import qualified Data.Semigroup as SG
+import qualified Data.Map as Map
+import qualified Data.IntMap as IntMap
+import qualified Data.HashMap.Strict as HashMap
+import qualified Data.Set as Set
+import qualified Control.Foldl as Foldl
+
+import Control.Arrow (second)
+import Control.Applicative
+import Control.Monad.Trans.Writer
+
+import Prelude (Bool (..), ($), IO, Eq (..), fromIntegral, Ord (..), String, mod, Int, Integer, show,
+                return, asTypeOf, (.), Show, (+), succ, Maybe (..), (*), mod, map, flip, otherwise, (-), div, maybe)
+import qualified Prelude
+
+newtype NonEmpty' a = NonEmpty' (NE.NonEmpty a)
+    deriving (Show, Eq)
+instance Arbitrary a => Arbitrary (NonEmpty' a) where
+    arbitrary = NonEmpty' <$> ((NE.:|) <$> arbitrary <*> arbitrary)
+
+-- | Arbitrary newtype for key-value pairs without any duplicate keys
+-- and is not empty
+newtype DuplPairs k v = DuplPairs { unDupl :: [(k,v)] }
+    deriving (Eq, Show)
+
+removeDuplicateKeys :: Ord k => [(k,v)] -> [(k,v)]
+removeDuplicateKeys m  = go Set.empty m
+    where go _ [] = []
+          go used ((k,v):xs)
+            | k `member` used = go used xs
+            | otherwise       = (k,v) : go (insertSet k used) xs
+
+instance (Arbitrary k, Arbitrary v, Ord k, Eq v) => Arbitrary (DuplPairs k v) where
+    arbitrary = DuplPairs . removeDuplicateKeys <$> arbitrary `suchThat` (/= [])
+    shrink (DuplPairs xs) =
+        map (DuplPairs . removeDuplicateKeys) $ filter (/= []) $ shrink xs
+
+-- | Arbitrary newtype for small lists whose length is <= 10
+--
+-- Used for testing 'unionsWith'
+newtype SmallList a = SmallList { getSmallList :: [a] }
+    deriving (Eq, Show, Ord)
+
+instance (Arbitrary a) => Arbitrary (SmallList a) where
+    arbitrary = SmallList <$> arbitrary `suchThat` ((<= 10) . olength)
+    shrink (SmallList xs) =
+        map SmallList $ filter ((<= 10) . olength) $ shrink xs
+
+-- | Choose a random key from a key-value pair list
+indexIn :: (Show k, Testable prop) => [(k,v)] -> (k -> prop) -> Property
+indexIn = forAll . elements . map Prelude.fst
+
+-- | Type restricted 'fromList'
+fromListAs :: IsSequence a => [Element a] -> a -> a
+fromListAs xs _ = fromList xs
+
+-- | Type restricted 'mapFromListAs'
+mapFromListAs :: IsMap a => [(ContainerKey a, MapValue a)] -> a -> a
+mapFromListAs xs _ = mapFromList xs
+
+main :: IO ()
+main = hspec $ do
+    describe "onull" $ do
+        it "works on empty lists"     $ onull []              @?= True
+        it "works on non-empty lists" $ onull [()]            @?= False
+        it "works on empty texts"     $ onull ("" :: Text)    @?= True
+        it "works on non-empty texts" $ onull ("foo" :: Text) @?= False
+
+    describe "osum" $ do
+        prop "works on lists" $ \(Small x) (Small y) ->
+            y >= x ==> osum [x..y] @?= ((x + y) * (y - x + 1) `div` (2 :: Int))
+
+    describe "oproduct" $ do
+        prop "works on lists" $ \(Positive x) (Positive y) ->
+            let fact n = oproduct [1..n]
+             in (y :: Integer) > (x :: Integer) ==>
+                    oproduct [x..y] @?= fact y `div` fact (x - 1)
+
+    describe "olength" $ do
+        prop "works on lists" $ \(NonNegative i) ->
+            olength (replicate i () :: [()]) @?= i
+        prop "works on texts" $ \(NonNegative i) ->
+            olength (replicate i 'a' :: Text) @?= i
+        prop "works on lazy bytestrings" $ \(NonNegative (Small i)) ->
+            olength64 (replicate i 6 :: L.ByteString) @?= i
+
+    describe "omap" $ do
+        prop "works on lists" $ \xs ->
+            omap (+1) xs @?= map (+1) (xs :: [Int])
+        prop "works on lazy bytestrings" $ \xs ->
+            omap (+1) (fromList xs :: L.ByteString) @?= fromList (map (+1) xs)
+        prop "works on texts" $ \xs ->
+            omap succ (fromList xs :: Text) @?= fromList (map succ xs)
+
+    describe "oconcatMap" $ do
+        prop "works on lists" $ \xs ->
+            oconcatMap (: []) xs @?= (xs :: [Int])
+
+    describe "ocompareLength" $ do
+        prop "works on lists" $ \(Positive i) j ->
+            ocompareLength (replicate i () :: [()]) j @?= compare i j
+
+    describe "groupAll" $ do
+        it "works on lists" $ groupAll ("abcabcabc" :: String) @?= ["aaa", "bbb", "ccc"]
+        it "works on texts" $ groupAll ("abcabcabc" :: Text)   @?= ["aaa", "bbb", "ccc"]
+
+    describe "unsnoc" $ do
+        let test name dummy = prop name $ \(QCM.NonEmpty xs) ->
+                let seq' = fromListAs xs dummy
+                 in case unsnoc seq' of
+                        Just (y, z) -> do
+                            y SG.<> singleton z @?= seq'
+                            snoc y z            @?= seq'
+                            otoList (snoc y z)  @?= xs
+                        Nothing -> expectationFailure "unsnoc returned Nothing"
+        test "works on lists" ([] :: [Int])
+        test "works on texts" ("" :: Text)
+        test "works on lazy bytestrings" L.empty
+
+    describe "index" $ do
+        let test name dummy = prop name $
+              \i' (QCM.NonEmpty xs) ->
+                let seq' = fromListAs xs dummy
+                    mx   = index xs (fromIntegral i)
+                    i    = fromIntegral (i' :: Int)
+                 in do
+                    mx @?= index seq' i
+                    case mx of
+                        Nothing -> return ()
+                        Just x  -> indexEx seq' i @?= x
+        test "works on lists" ([] :: [Int])
+        test "works on strict texts" ("" :: Text)
+        test "works on lazy texts" ("" :: TL.Text)
+        test "works on strict bytestrings" S.empty
+        test "works on lazy bytestrings" L.empty
+        test "works on Vector" (V.singleton (1 :: Int))
+        test "works on SVector" (VS.singleton (1 :: Int))
+        test "works on UVector" (U.singleton (1 :: Int))
+        test "works on Seq" (Seq.fromList [1 :: Int])
+
+    describe "groupAllOn" $ do
+        it "works on lists" $
+            groupAllOn (`mod` 3) ([1..9] :: [Int]) @?= [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
+
+    describe "breakWord" $ do
+        let test x y z = it (show (x, y, z)) $ breakWord (x :: Text) @?= (y, z)
+        test "hello world" "hello" "world"
+        test "hello     world" "hello" "world"
+        test "hello\r\nworld" "hello" "world"
+        test "hello there  world" "hello" "there  world"
+        test "" "" ""
+        test "hello    \n\r\t" "hello" ""
+
+    describe "breakLine" $ do
+        let test x y z = it (show (x, y, z)) $ breakLine (x :: Text) @?= (y, z)
+        test "hello world" "hello world" ""
+        test "hello\r\n world" "hello" " world"
+        test "hello\n world" "hello" " world"
+        test "hello\r world" "hello\r world" ""
+        test "hello\r\nworld" "hello" "world"
+        test "hello\r\nthere\nworld" "hello" "there\nworld"
+        test "hello\n\r\nworld" "hello" "\r\nworld"
+        test "" "" ""
+
+    describe "omapM_" $ do
+        let test typ dummy = prop typ $ \input ->
+                input @?= execWriter (omapM_ (tell . return) (fromListAs input dummy))
+        test "works on strict bytestrings" S.empty
+        test "works on lazy bytestrings" L.empty
+        test "works on strict texts" T.empty
+        test "works on lazy texts" TL.empty
+
+    describe "NonNull" $ do
+        describe "fromNonEmpty" $ do
+            prop "toMinList" $ \(NonEmpty' ne) ->
+                (NE.toList ne :: [Int]) @?= NN.toNullable (NN.toMinList ne)
+        describe "toNonEmpty" $ do
+            it "converts nonnull to nonempty" $ do
+                NN.toNonEmpty (NN.impureNonNull [1,2,3]) @?= NE.fromList [1,2,3]
+
+        describe "mapNonNull" $ do
+            prop "mapNonNull id == id" $ \x xs ->
+                let nonNull = NN.ncons x (xs :: [Int])
+                in NN.mapNonNull Prelude.id nonNull @?= nonNull
+            prop "mapNonNull (f . g) == mapNonNull f . mapNonNull g" $
+                \(Fn (f :: Integer -> String)) (Fn (g :: Int -> Integer)) x xs ->
+                    let nns = NN.ncons x (xs :: [Int])
+                    in NN.mapNonNull (f . g) nns @?= NN.mapNonNull f (NN.mapNonNull g nns)
+
+        let -- | Type restricted 'NN.ncons'
+            nconsAs :: IsSequence seq => Element seq -> [Element seq] -> seq -> NN.NonNull seq
+            nconsAs x xs _ = NN.ncons x (fromList xs)
+
+            test :: (IsSequence typ, Ord (Element typ), Arbitrary (Element typ), Show (Element typ), Show typ, Eq typ, Eq (Element typ))
+                 => String -> typ -> Spec
+            test typ du = describe typ $ do
+                prop "head" $ \x xs ->
+                    NN.head (nconsAs x xs du) @?= x
+                prop "tail" $ \x xs ->
+                    NN.tail (nconsAs x xs du) @?= fromList xs
+                prop "last" $ \x xs ->
+                    NN.last (reverse $ nconsAs x xs du) @?= x
+                prop "init" $ \x xs ->
+                    NN.init (reverse $ nconsAs x xs du) @?= reverse (fromList xs)
+                prop "maximum" $ \x xs ->
+                    NN.maximum (nconsAs x xs du) @?= Prelude.maximum (x:xs)
+                prop "maximumBy" $ \x xs ->
+                    NN.maximumBy compare (nconsAs x xs du) @?= Prelude.maximum (x:xs)
+                prop "minimum" $ \x xs ->
+                    NN.minimum (nconsAs x xs du) @?= Prelude.minimum (x:xs)
+                prop "minimumBy" $ \x xs ->
+                    NN.minimumBy compare (nconsAs x xs du) @?= Prelude.minimum (x:xs)
+                prop "ofoldMap1" $ \x xs ->
+                    SG.getMax (NN.ofoldMap1 SG.Max $ nconsAs x xs du) @?= Prelude.maximum (x:xs)
+                prop "ofoldr1" $ \x xs ->
+                    NN.ofoldr1 Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)
+                prop "ofoldl1'" $ \x xs ->
+                    NN.ofoldl1' Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)
+
+        test "Strict ByteString" S.empty
+        test "Lazy ByteString" L.empty
+        test "Strict Text" T.empty
+        test "Lazy Text" TL.empty
+        test "Vector" (V.empty :: V.Vector Int)
+        test "Unboxed Vector" (U.empty :: U.Vector Int)
+        test "Storable Vector" (VS.empty :: VS.Vector Int)
+        test "List" ([5 :: Int])
+
+    describe "Containers" $ do
+        let test typ dummy xlookup xinsert xdelete = describe typ $ do
+                prop "difference" $ \(DuplPairs xs) (DuplPairs ys) ->
+                    let m1 = mapFromList xs `difference` mapFromList ys
+                        m2 = mapFromListAs (xs `difference` ys) dummy
+                     in m1 @?= m2
+
+                prop "lookup" $ \(DuplPairs xs) -> indexIn xs $ \k ->
+                    let m = mapFromListAs xs dummy
+                        v1 = lookup k m
+                    in do
+                        v1 @?= lookup k xs
+                        v1 @?= xlookup k m
+
+                prop "insert" $ \(DuplPairs xs) v -> indexIn xs $ \k ->
+                    let m = mapFromListAs xs dummy
+                        m1 = insertMap k v m
+                     in do
+                        m1 @?= mapFromList (insertMap k v xs)
+                        m1 @?= xinsert k v m
+
+                prop "delete" $ \(DuplPairs xs) -> indexIn xs $ \k ->
+                    let m = mapFromListAs xs dummy
+                        m1 = deleteMap k m
+                     in do
+                        m1 @?= mapFromList (deleteMap k xs)
+                        m1 @?= xdelete k m
+
+                prop "singletonMap" $ \k v ->
+                    singletonMap k v @?= (mapFromListAs [(k, v)] dummy)
+
+                prop "findWithDefault" $ \(DuplPairs xs) k v ->
+                    findWithDefault v k (mapFromListAs xs dummy)
+                        @?= findWithDefault v k xs
+
+                prop "insertWith" $ \(DuplPairs xs) k v ->
+                    insertWith (+) k v (mapFromListAs xs dummy)
+                        @?= mapFromList (insertWith (+) k v xs)
+
+                prop "insertWithKey" $ \(DuplPairs xs) k v ->
+                    let m = mapFromListAs xs dummy
+                        f x y z = x + y + z
+                     in insertWithKey f k v m
+                            @?= mapFromList (insertWithKey f k v xs)
+
+                prop "insertLookupWithKey" $ \(DuplPairs xs) k v ->
+                    let m = mapFromListAs xs dummy
+                        f x y z = x + y + z
+                     in insertLookupWithKey f k v m @?=
+                            second mapFromList (insertLookupWithKey f k v xs)
+
+                prop "adjustMap" $ \(DuplPairs xs) k ->
+                    adjustMap succ k (mapFromListAs xs dummy)
+                        @?= mapFromList (adjustMap succ k xs)
+
+                prop "adjustWithKey" $ \(DuplPairs xs) k ->
+                    adjustWithKey (+) k (mapFromListAs xs dummy)
+                        @?= mapFromList (adjustWithKey (+) k xs)
+
+                prop "updateMap" $ \(DuplPairs xs) k ->
+                    let f i = if i < 0 then Nothing else Just $ i * 2
+                     in updateMap f k (mapFromListAs xs dummy)
+                            @?= mapFromList (updateMap f k xs)
+
+                prop "updateWithKey" $ \(DuplPairs xs) k' ->
+                    let f k i = if i < 0 then Nothing else Just $ i * k
+                     in updateWithKey f k' (mapFromListAs xs dummy)
+                            @?= mapFromList (updateWithKey f k' xs)
+
+                prop "updateLookupWithKey" $ \(DuplPairs xs) k' ->
+                    let f k i = if i < 0 then Nothing else Just $ i * k
+                     in updateLookupWithKey f k' (mapFromListAs xs dummy)
+                            @?= second mapFromList (updateLookupWithKey f k' xs)
+
+                prop "alter" $ \(DuplPairs xs) k ->
+                    let m = mapFromListAs xs dummy
+                        f Nothing = Just (-1)
+                        f (Just i) = if i < 0 then Nothing else Just (i * 2)
+                     in lookup k (alterMap f k m) @?= f (lookup k m)
+
+                prop "unionWith" $ \(DuplPairs xs) (DuplPairs ys) ->
+                    let m1 = unionWith (+)
+                                (mapFromListAs xs dummy)
+                                (mapFromListAs ys dummy)
+                        m2 = mapFromList (unionWith (+) xs ys)
+                     in m1 @?= m2
+
+                prop "unionWithKey" $ \(DuplPairs xs) (DuplPairs ys) ->
+                    let f k x y = k + x + y
+                        m1 = unionWithKey f
+                                (mapFromListAs xs dummy)
+                                (mapFromListAs ys dummy)
+                        m2 = mapFromList (unionWithKey f xs ys)
+                     in m1 @?= m2
+
+                prop "unionsWith" $ \(SmallList xss) ->
+                    let duplXss = map unDupl xss
+                        ms = map mapFromList duplXss `asTypeOf` [dummy]
+                     in unionsWith (+) ms
+                            @?= mapFromList (unionsWith (+) duplXss)
+
+                prop "mapWithKey" $ \(DuplPairs xs) ->
+                    let m1 = mapWithKey (+) (mapFromList xs) `asTypeOf` dummy
+                        m2 = mapFromList $ mapWithKey (+) xs
+                     in m1 @?= m2
+
+                prop "omapKeysWith" $ \(DuplPairs xs) ->
+                    let f = flip mod 5
+                        m1 = omapKeysWith (+) f (mapFromList xs) `asTypeOf` dummy
+                        m2 = mapFromList $ omapKeysWith (+) f xs
+                     in m1 @?= m2
+
+        test "Data.Map" (Map.empty :: Map.Map Int Int)
+            Map.lookup Map.insert Map.delete
+        test "Data.IntMap" (IntMap.empty :: IntMap.IntMap Int)
+            IntMap.lookup IntMap.insert IntMap.delete
+        test "Data.HashMap" (HashMap.empty :: HashMap.HashMap Int Int)
+            HashMap.lookup HashMap.insert HashMap.delete
+
+    describe "Foldl Integration" $ do
+        prop "vector" $ \xs -> do
+#if MIN_VERSION_foldl(1,3,0)
+            let x1 = Foldl.fold Foldl.vector (xs :: [Int])
+                x2 = Foldl.purely ofoldlUnwrap Foldl.vector xs
+#else
+            x1 <- Foldl.foldM Foldl.vector (xs :: [Int])
+            x2 <- Foldl.impurely ofoldMUnwrap Foldl.vector xs
+#endif
+            x2 @?= (x1 :: V.Vector Int)
+        prop "length" $ \xs -> do
+            let x1 = Foldl.fold Foldl.length (xs :: [Int])
+                x2 = Foldl.purely ofoldlUnwrap Foldl.length xs
+            x2 @?= x1
+
+    describe "Replacing" $ do
+        let test typ dummy = describe typ $ do
+                prop "replaceElem old new === omap (\\x -> if x == old then new else x)" $
+                    -- replace random element or any random value with random new value
+                    \x list new -> forAll (elements (x:list)) $ \old ->
+                    let seq' = fromListAs list dummy
+                    in replaceElem old new seq' @?= omap (\x' -> if x' == old then new else x') seq'
+#if MIN_VERSION_QuickCheck(2,8,0)
+                prop "replaceSeq old new === ointercalate new . splitSeq old" $
+                    -- replace random subsequence with random new sequence
+                    \list new -> forAll (sublistOf list) $ \old ->
+                    let [seq', old', new'] = map (`fromListAs` dummy) [list, old, new]
+                    in replaceSeq old' new' seq' @?= ointercalate new' (splitSeq old' seq')
+                prop "replaceSeq old old === id" $ \list -> forAll (sublistOf list) $ \old ->
+                    let [seq', old'] = map (`fromListAs` dummy) [list, old]
+                    in replaceSeq old' old' seq' @?= seq'
+#endif
+        test "List" ([] :: [Int])
+        test "Vector" (V.empty :: V.Vector Int)
+        test "Storable Vector" (VS.empty :: VS.Vector Int)
+        test "Unboxed Vector" (U.empty :: U.Vector Int)
+        test "Strict ByteString" S.empty
+        test "Lazy ByteString" L.empty
+        test "Strict Text" T.empty
+        test "Lazy Text" TL.empty
+
+    describe "Sorting" $ do
+        let test typ dummy = describe typ $ do
+                prop "sortBy" $ \input -> do
+                    let f x y = compare y x
+                    fromList (sortBy f input) @?= sortBy f (fromListAs input dummy)
+                prop "sort" $ \input ->
+                    fromList (sort input) @?= sort (fromListAs input dummy)
+        test "List" ([] :: [Int])
+        test "Vector" (V.empty :: V.Vector Int)
+        test "Storable Vector" (VS.empty :: VS.Vector Int)
+        test "Unboxed Vector" (U.empty :: U.Vector Int)
+        test "Strict ByteString" S.empty
+        test "Lazy ByteString" L.empty
+        test "Strict Text" T.empty
+        test "Lazy Text" TL.empty
+
+    describe "Intercalate" $ do
+        let test typ dummy = describe typ $ do
+                prop "intercalate === defaultIntercalate" $ \list lists ->
+                    let seq' = fromListAs list dummy
+                        seqs = map (`fromListAs` dummy) lists
+                    in ointercalate seq' seqs @?= fromList (List.intercalate list lists)
+        test "List" ([] :: [Int])
+        test "Vector" (V.empty :: V.Vector Int)
+        test "Storable Vector" (VS.empty :: VS.Vector Int)
+        test "Unboxed Vector" (U.empty :: U.Vector Int)
+        test "Strict ByteString" S.empty
+        test "Lazy ByteString" L.empty
+        test "Strict Text" T.empty
+        test "Lazy Text" TL.empty
+
+    describe "Splitting" $ do
+        let test typ dummy = describe typ $ do
+                let fromList' = (`fromListAs` dummy)
+                let fromSepList sep = fromList' . map (fromMaybe sep)
+                prop "intercalate sep . splitSeq sep === id" $
+                    \(fromList' -> sep) ->
+                    \(mconcat . map (maybe sep fromList') -> xs) ->
+                    ointercalate sep (splitSeq sep xs) @?= xs
+                prop "splitSeq mempty xs === mempty : map singleton (otoList xs)" $
+                    \input ->
+                    splitSeq mempty (fromList' input) @?= mempty : map singleton input
+                prop "splitSeq _ mempty == [mempty]" $
+                    \(fromList' -> sep) ->
+                    splitSeq sep mempty @?= [mempty]
+                prop "intercalate (singleton sep) . splitElem sep === id" $
+                    \sep -> \(fromSepList sep -> xs) ->
+                    ointercalate (singleton sep) (splitElem sep xs) @?= xs
+                prop "length . splitElem sep === succ . length . filter (== sep)" $
+                    \sep -> \(fromSepList sep -> xs) ->
+                    olength (splitElem sep xs) @?= olength (filter (== sep) xs) + 1
+                prop "splitElem sep (replicate n sep) == replicate (n+1) mempty" $
+                    \(NonNegative n) sep ->
+                    splitElem sep (fromList' (replicate n sep)) @?= replicate (n + 1) mempty
+                prop "splitElem sep === splitWhen (== sep)" $
+                    \sep -> \(fromSepList sep -> xs) ->
+                    splitElem sep xs @?= splitWhen (== sep) xs
+                prop "splitElem sep === splitSeq (singleton sep)" $
+                    \sep -> \(fromSepList sep -> xs) ->
+                    splitElem sep xs @?= splitSeq (singleton sep) xs
+        test "List" ([] :: [Int])
+        test "Vector" (V.empty :: V.Vector Int)
+        test "Storable Vector" (VS.empty :: VS.Vector Int)
+        test "Unboxed Vector" (U.empty :: U.Vector Int)
+        test "Strict ByteString" S.empty
+        test "Lazy ByteString" L.empty
+        test "Strict Text" T.empty
+        test "Lazy Text" TL.empty
+
+    describe "Other Issues" $ do
+        it "#26 headEx on a list works" $
+            headEx (1 : filter Prelude.odd [2,4..]) @?= (1 :: Int)
+
+        it "#31 find doesn't infinitely loop on NonEmpty" $
+            find (== "a") ("a" NE.:| ["d","fgf"]) @?= Just ("a" :: String)
+
+        it "#83 head on Seq works correctly" $ do
+            headEx (Seq.fromList [1 :: Int,2,3]) @?= (1 :: Int)
+            headMay (Seq.fromList [] :: Seq.Seq Int) @?= Nothing
diff --git a/test/Spec.hs b/test/Spec.hs
deleted file mode 100644
--- a/test/Spec.hs
+++ /dev/null
@@ -1,502 +0,0 @@
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE ViewPatterns #-}
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE PatternSynonyms #-}
-
-module Spec where
-
-import Data.MonoTraversable
-import Data.Containers
-import Data.Sequences
-import qualified Data.Sequence as Seq
-import qualified Data.NonNull as NN
-import Data.Monoid (mempty, mconcat)
-import Data.Maybe (fromMaybe)
-import qualified Data.List as List
-
-import Test.Hspec
-import Test.Hspec.QuickCheck
-import Test.HUnit ((@?=))
-import Test.QuickCheck hiding (NonEmptyList(..))
-import Test.QuickCheck.Function (pattern Fn)
-import qualified Test.QuickCheck.Modifiers as QCM
-
-import Data.Text (Text)
-import qualified Data.Text as T
-import qualified Data.Text.Lazy as TL
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Lazy as L
-import qualified Data.Vector as V
-import qualified Data.Vector.Unboxed as U
-import qualified Data.Vector.Storable as VS
-import qualified Data.List.NonEmpty as NE
-import qualified Data.Semigroup as SG
-import qualified Data.Map as Map
-import qualified Data.IntMap as IntMap
-import qualified Data.HashMap.Strict as HashMap
-import qualified Data.Set as Set
-import qualified Control.Foldl as Foldl
-
-import Control.Arrow (second)
-import Control.Applicative
-import Control.Monad.Trans.Writer
-
-import Prelude (Bool (..), ($), IO, Eq (..), fromIntegral, Ord (..), String, mod, Int, Integer, show,
-                return, asTypeOf, (.), Show, (+), succ, Maybe (..), (*), mod, map, flip, otherwise, (-), div, maybe)
-import qualified Prelude
-
-newtype NonEmpty' a = NonEmpty' (NE.NonEmpty a)
-    deriving (Show, Eq)
-instance Arbitrary a => Arbitrary (NonEmpty' a) where
-    arbitrary = NonEmpty' <$> ((NE.:|) <$> arbitrary <*> arbitrary)
-
--- | Arbitrary newtype for key-value pairs without any duplicate keys
--- and is not empty
-newtype DuplPairs k v = DuplPairs { unDupl :: [(k,v)] }
-    deriving (Eq, Show)
-
-removeDuplicateKeys :: Ord k => [(k,v)] -> [(k,v)]
-removeDuplicateKeys m  = go Set.empty m
-    where go _ [] = []
-          go used ((k,v):xs)
-            | k `member` used = go used xs
-            | otherwise       = (k,v) : go (insertSet k used) xs
-
-instance (Arbitrary k, Arbitrary v, Ord k, Eq v) => Arbitrary (DuplPairs k v) where
-    arbitrary = DuplPairs . removeDuplicateKeys <$> arbitrary `suchThat` (/= [])
-    shrink (DuplPairs xs) =
-        map (DuplPairs . removeDuplicateKeys) $ filter (/= []) $ shrink xs
-
--- | Arbitrary newtype for small lists whose length is <= 10
---
--- Used for testing 'unionsWith'
-newtype SmallList a = SmallList { getSmallList :: [a] }
-    deriving (Eq, Show, Ord)
-
-instance (Arbitrary a) => Arbitrary (SmallList a) where
-    arbitrary = SmallList <$> arbitrary `suchThat` ((<= 10) . olength)
-    shrink (SmallList xs) =
-        map SmallList $ filter ((<= 10) . olength) $ shrink xs
-
--- | Choose a random key from a key-value pair list
-indexIn :: (Show k, Testable prop) => [(k,v)] -> (k -> prop) -> Property
-indexIn = forAll . elements . map Prelude.fst
-
--- | Type restricted 'fromList'
-fromListAs :: IsSequence a => [Element a] -> a -> a
-fromListAs xs _ = fromList xs
-
--- | Type restricted 'mapFromListAs'
-mapFromListAs :: IsMap a => [(ContainerKey a, MapValue a)] -> a -> a
-mapFromListAs xs _ = mapFromList xs
-
-main :: IO ()
-main = hspec $ do
-    describe "onull" $ do
-        it "works on empty lists"     $ onull []              @?= True
-        it "works on non-empty lists" $ onull [()]            @?= False
-        it "works on empty texts"     $ onull ("" :: Text)    @?= True
-        it "works on non-empty texts" $ onull ("foo" :: Text) @?= False
-
-    describe "osum" $ do
-        prop "works on lists" $ \(Small x) (Small y) ->
-            y >= x ==> osum [x..y] @?= ((x + y) * (y - x + 1) `div` (2 :: Int))
-
-    describe "oproduct" $ do
-        prop "works on lists" $ \(Positive x) (Positive y) ->
-            let fact n = oproduct [1..n]
-             in (y :: Integer) > (x :: Integer) ==>
-                    oproduct [x..y] @?= fact y `div` fact (x - 1)
-
-    describe "olength" $ do
-        prop "works on lists" $ \(NonNegative i) ->
-            olength (replicate i () :: [()]) @?= i
-        prop "works on texts" $ \(NonNegative i) ->
-            olength (replicate i 'a' :: Text) @?= i
-        prop "works on lazy bytestrings" $ \(NonNegative (Small i)) ->
-            olength64 (replicate i 6 :: L.ByteString) @?= i
-
-    describe "omap" $ do
-        prop "works on lists" $ \xs ->
-            omap (+1) xs @?= map (+1) (xs :: [Int])
-        prop "works on lazy bytestrings" $ \xs ->
-            omap (+1) (fromList xs :: L.ByteString) @?= fromList (map (+1) xs)
-        prop "works on texts" $ \xs ->
-            omap succ (fromList xs :: Text) @?= fromList (map succ xs)
-
-    describe "oconcatMap" $ do
-        prop "works on lists" $ \xs ->
-            oconcatMap (: []) xs @?= (xs :: [Int])
-
-    describe "ocompareLength" $ do
-        prop "works on lists" $ \(Positive i) j ->
-            ocompareLength (replicate i () :: [()]) j @?= compare i j
-
-    describe "groupAll" $ do
-        it "works on lists" $ groupAll ("abcabcabc" :: String) @?= ["aaa", "bbb", "ccc"]
-        it "works on texts" $ groupAll ("abcabcabc" :: Text)   @?= ["aaa", "bbb", "ccc"]
-
-    describe "unsnoc" $ do
-        let test name dummy = prop name $ \(QCM.NonEmpty xs) ->
-                let seq' = fromListAs xs dummy
-                 in case unsnoc seq' of
-                        Just (y, z) -> do
-                            y SG.<> singleton z @?= seq'
-                            snoc y z            @?= seq'
-                            otoList (snoc y z)  @?= xs
-                        Nothing -> expectationFailure "unsnoc returned Nothing"
-        test "works on lists" ([] :: [Int])
-        test "works on texts" ("" :: Text)
-        test "works on lazy bytestrings" L.empty
-
-    describe "index" $ do
-        let test name dummy = prop name $
-              \i' (QCM.NonEmpty xs) ->
-                let seq' = fromListAs xs dummy
-                    mx   = index xs (fromIntegral i)
-                    i    = fromIntegral (i' :: Int)
-                 in do
-                    mx @?= index seq' i
-                    case mx of
-                        Nothing -> return ()
-                        Just x  -> indexEx seq' i @?= x
-        test "works on lists" ([] :: [Int])
-        test "works on strict texts" ("" :: Text)
-        test "works on lazy texts" ("" :: TL.Text)
-        test "works on strict bytestrings" S.empty
-        test "works on lazy bytestrings" L.empty
-        test "works on Vector" (V.singleton (1 :: Int))
-        test "works on SVector" (VS.singleton (1 :: Int))
-        test "works on UVector" (U.singleton (1 :: Int))
-        test "works on Seq" (Seq.fromList [1 :: Int])
-
-    describe "groupAllOn" $ do
-        it "works on lists" $
-            groupAllOn (`mod` 3) ([1..9] :: [Int]) @?= [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
-
-    describe "breakWord" $ do
-        let test x y z = it (show (x, y, z)) $ breakWord (x :: Text) @?= (y, z)
-        test "hello world" "hello" "world"
-        test "hello     world" "hello" "world"
-        test "hello\r\nworld" "hello" "world"
-        test "hello there  world" "hello" "there  world"
-        test "" "" ""
-        test "hello    \n\r\t" "hello" ""
-
-    describe "breakLine" $ do
-        let test x y z = it (show (x, y, z)) $ breakLine (x :: Text) @?= (y, z)
-        test "hello world" "hello world" ""
-        test "hello\r\n world" "hello" " world"
-        test "hello\n world" "hello" " world"
-        test "hello\r world" "hello\r world" ""
-        test "hello\r\nworld" "hello" "world"
-        test "hello\r\nthere\nworld" "hello" "there\nworld"
-        test "hello\n\r\nworld" "hello" "\r\nworld"
-        test "" "" ""
-
-    describe "omapM_" $ do
-        let test typ dummy = prop typ $ \input ->
-                input @?= execWriter (omapM_ (tell . return) (fromListAs input dummy))
-        test "works on strict bytestrings" S.empty
-        test "works on lazy bytestrings" L.empty
-        test "works on strict texts" T.empty
-        test "works on lazy texts" TL.empty
-
-    describe "NonNull" $ do
-        describe "fromNonEmpty" $ do
-            prop "toMinList" $ \(NonEmpty' ne) ->
-                (NE.toList ne :: [Int]) @?= NN.toNullable (NN.toMinList ne)
-        describe "toNonEmpty" $ do
-            it "converts nonnull to nonempty" $ do
-                NN.toNonEmpty (NN.impureNonNull [1,2,3]) @?= NE.fromList [1,2,3]
-
-        describe "mapNonNull" $ do
-            prop "mapNonNull id == id" $ \x xs ->
-                let nonNull = NN.ncons x (xs :: [Int])
-                in NN.mapNonNull Prelude.id nonNull @?= nonNull
-            prop "mapNonNull (f . g) == mapNonNull f . mapNonNull g" $
-                \(Fn (f :: Integer -> String)) (Fn (g :: Int -> Integer)) x xs ->
-                    let nns = NN.ncons x (xs :: [Int])
-                    in NN.mapNonNull (f . g) nns @?= NN.mapNonNull f (NN.mapNonNull g nns)
-
-        let -- | Type restricted 'NN.ncons'
-            nconsAs :: IsSequence seq => Element seq -> [Element seq] -> seq -> NN.NonNull seq
-            nconsAs x xs _ = NN.ncons x (fromList xs)
-
-            test :: (IsSequence typ, Ord (Element typ), Arbitrary (Element typ), Show (Element typ), Show typ, Eq typ, Eq (Element typ))
-                 => String -> typ -> Spec
-            test typ du = describe typ $ do
-                prop "head" $ \x xs ->
-                    NN.head (nconsAs x xs du) @?= x
-                prop "tail" $ \x xs ->
-                    NN.tail (nconsAs x xs du) @?= fromList xs
-                prop "last" $ \x xs ->
-                    NN.last (reverse $ nconsAs x xs du) @?= x
-                prop "init" $ \x xs ->
-                    NN.init (reverse $ nconsAs x xs du) @?= reverse (fromList xs)
-                prop "maximum" $ \x xs ->
-                    NN.maximum (nconsAs x xs du) @?= Prelude.maximum (x:xs)
-                prop "maximumBy" $ \x xs ->
-                    NN.maximumBy compare (nconsAs x xs du) @?= Prelude.maximum (x:xs)
-                prop "minimum" $ \x xs ->
-                    NN.minimum (nconsAs x xs du) @?= Prelude.minimum (x:xs)
-                prop "minimumBy" $ \x xs ->
-                    NN.minimumBy compare (nconsAs x xs du) @?= Prelude.minimum (x:xs)
-                prop "ofoldMap1" $ \x xs ->
-                    SG.getMax (NN.ofoldMap1 SG.Max $ nconsAs x xs du) @?= Prelude.maximum (x:xs)
-                prop "ofoldr1" $ \x xs ->
-                    NN.ofoldr1 Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)
-                prop "ofoldl1'" $ \x xs ->
-                    NN.ofoldl1' Prelude.min (nconsAs x xs du) @?= Prelude.minimum (x:xs)
-
-        test "Strict ByteString" S.empty
-        test "Lazy ByteString" L.empty
-        test "Strict Text" T.empty
-        test "Lazy Text" TL.empty
-        test "Vector" (V.empty :: V.Vector Int)
-        test "Unboxed Vector" (U.empty :: U.Vector Int)
-        test "Storable Vector" (VS.empty :: VS.Vector Int)
-        test "List" ([5 :: Int])
-
-    describe "Containers" $ do
-        let test typ dummy xlookup xinsert xdelete = describe typ $ do
-                prop "difference" $ \(DuplPairs xs) (DuplPairs ys) ->
-                    let m1 = mapFromList xs `difference` mapFromList ys
-                        m2 = mapFromListAs (xs `difference` ys) dummy
-                     in m1 @?= m2
-
-                prop "lookup" $ \(DuplPairs xs) -> indexIn xs $ \k ->
-                    let m = mapFromListAs xs dummy
-                        v1 = lookup k m
-                    in do
-                        v1 @?= lookup k xs
-                        v1 @?= xlookup k m
-
-                prop "insert" $ \(DuplPairs xs) v -> indexIn xs $ \k ->
-                    let m = mapFromListAs xs dummy
-                        m1 = insertMap k v m
-                     in do
-                        m1 @?= mapFromList (insertMap k v xs)
-                        m1 @?= xinsert k v m
-
-                prop "delete" $ \(DuplPairs xs) -> indexIn xs $ \k ->
-                    let m = mapFromListAs xs dummy
-                        m1 = deleteMap k m
-                     in do
-                        m1 @?= mapFromList (deleteMap k xs)
-                        m1 @?= xdelete k m
-
-                prop "singletonMap" $ \k v ->
-                    singletonMap k v @?= (mapFromListAs [(k, v)] dummy)
-
-                prop "findWithDefault" $ \(DuplPairs xs) k v ->
-                    findWithDefault v k (mapFromListAs xs dummy)
-                        @?= findWithDefault v k xs
-
-                prop "insertWith" $ \(DuplPairs xs) k v ->
-                    insertWith (+) k v (mapFromListAs xs dummy)
-                        @?= mapFromList (insertWith (+) k v xs)
-
-                prop "insertWithKey" $ \(DuplPairs xs) k v ->
-                    let m = mapFromListAs xs dummy
-                        f x y z = x + y + z
-                     in insertWithKey f k v m
-                            @?= mapFromList (insertWithKey f k v xs)
-
-                prop "insertLookupWithKey" $ \(DuplPairs xs) k v ->
-                    let m = mapFromListAs xs dummy
-                        f x y z = x + y + z
-                     in insertLookupWithKey f k v m @?=
-                            second mapFromList (insertLookupWithKey f k v xs)
-
-                prop "adjustMap" $ \(DuplPairs xs) k ->
-                    adjustMap succ k (mapFromListAs xs dummy)
-                        @?= mapFromList (adjustMap succ k xs)
-
-                prop "adjustWithKey" $ \(DuplPairs xs) k ->
-                    adjustWithKey (+) k (mapFromListAs xs dummy)
-                        @?= mapFromList (adjustWithKey (+) k xs)
-
-                prop "updateMap" $ \(DuplPairs xs) k ->
-                    let f i = if i < 0 then Nothing else Just $ i * 2
-                     in updateMap f k (mapFromListAs xs dummy)
-                            @?= mapFromList (updateMap f k xs)
-
-                prop "updateWithKey" $ \(DuplPairs xs) k' ->
-                    let f k i = if i < 0 then Nothing else Just $ i * k
-                     in updateWithKey f k' (mapFromListAs xs dummy)
-                            @?= mapFromList (updateWithKey f k' xs)
-
-                prop "updateLookupWithKey" $ \(DuplPairs xs) k' ->
-                    let f k i = if i < 0 then Nothing else Just $ i * k
-                     in updateLookupWithKey f k' (mapFromListAs xs dummy)
-                            @?= second mapFromList (updateLookupWithKey f k' xs)
-
-                prop "alter" $ \(DuplPairs xs) k ->
-                    let m = mapFromListAs xs dummy
-                        f Nothing = Just (-1)
-                        f (Just i) = if i < 0 then Nothing else Just (i * 2)
-                     in lookup k (alterMap f k m) @?= f (lookup k m)
-
-                prop "unionWith" $ \(DuplPairs xs) (DuplPairs ys) ->
-                    let m1 = unionWith (+)
-                                (mapFromListAs xs dummy)
-                                (mapFromListAs ys dummy)
-                        m2 = mapFromList (unionWith (+) xs ys)
-                     in m1 @?= m2
-
-                prop "unionWithKey" $ \(DuplPairs xs) (DuplPairs ys) ->
-                    let f k x y = k + x + y
-                        m1 = unionWithKey f
-                                (mapFromListAs xs dummy)
-                                (mapFromListAs ys dummy)
-                        m2 = mapFromList (unionWithKey f xs ys)
-                     in m1 @?= m2
-
-                prop "unionsWith" $ \(SmallList xss) ->
-                    let duplXss = map unDupl xss
-                        ms = map mapFromList duplXss `asTypeOf` [dummy]
-                     in unionsWith (+) ms
-                            @?= mapFromList (unionsWith (+) duplXss)
-
-                prop "mapWithKey" $ \(DuplPairs xs) ->
-                    let m1 = mapWithKey (+) (mapFromList xs) `asTypeOf` dummy
-                        m2 = mapFromList $ mapWithKey (+) xs
-                     in m1 @?= m2
-
-                prop "omapKeysWith" $ \(DuplPairs xs) ->
-                    let f = flip mod 5
-                        m1 = omapKeysWith (+) f (mapFromList xs) `asTypeOf` dummy
-                        m2 = mapFromList $ omapKeysWith (+) f xs
-                     in m1 @?= m2
-
-        test "Data.Map" (Map.empty :: Map.Map Int Int)
-            Map.lookup Map.insert Map.delete
-        test "Data.IntMap" (IntMap.empty :: IntMap.IntMap Int)
-            IntMap.lookup IntMap.insert IntMap.delete
-        test "Data.HashMap" (HashMap.empty :: HashMap.HashMap Int Int)
-            HashMap.lookup HashMap.insert HashMap.delete
-
-    describe "Foldl Integration" $ do
-        prop "vector" $ \xs -> do
-#if MIN_VERSION_foldl(1,3,0)
-            let x1 = Foldl.fold Foldl.vector (xs :: [Int])
-                x2 = Foldl.purely ofoldlUnwrap Foldl.vector xs
-#else
-            x1 <- Foldl.foldM Foldl.vector (xs :: [Int])
-            x2 <- Foldl.impurely ofoldMUnwrap Foldl.vector xs
-#endif
-            x2 @?= (x1 :: V.Vector Int)
-        prop "length" $ \xs -> do
-            let x1 = Foldl.fold Foldl.length (xs :: [Int])
-                x2 = Foldl.purely ofoldlUnwrap Foldl.length xs
-            x2 @?= x1
-
-    describe "Replacing" $ do
-        let test typ dummy = describe typ $ do
-                prop "replaceElem old new === omap (\\x -> if x == old then new else x)" $
-                    -- replace random element or any random value with random new value
-                    \x list new -> forAll (elements (x:list)) $ \old ->
-                    let seq' = fromListAs list dummy
-                    in replaceElem old new seq' @?= omap (\x' -> if x' == old then new else x') seq'
-#if MIN_VERSION_QuickCheck(2,8,0)
-                prop "replaceSeq old new === ointercalate new . splitSeq old" $
-                    -- replace random subsequence with random new sequence
-                    \list new -> forAll (sublistOf list) $ \old ->
-                    let [seq', old', new'] = map (`fromListAs` dummy) [list, old, new]
-                    in replaceSeq old' new' seq' @?= ointercalate new' (splitSeq old' seq')
-                prop "replaceSeq old old === id" $ \list -> forAll (sublistOf list) $ \old ->
-                    let [seq', old'] = map (`fromListAs` dummy) [list, old]
-                    in replaceSeq old' old' seq' @?= seq'
-#endif
-        test "List" ([] :: [Int])
-        test "Vector" (V.empty :: V.Vector Int)
-        test "Storable Vector" (VS.empty :: VS.Vector Int)
-        test "Unboxed Vector" (U.empty :: U.Vector Int)
-        test "Strict ByteString" S.empty
-        test "Lazy ByteString" L.empty
-        test "Strict Text" T.empty
-        test "Lazy Text" TL.empty
-
-    describe "Sorting" $ do
-        let test typ dummy = describe typ $ do
-                prop "sortBy" $ \input -> do
-                    let f x y = compare y x
-                    fromList (sortBy f input) @?= sortBy f (fromListAs input dummy)
-                prop "sort" $ \input ->
-                    fromList (sort input) @?= sort (fromListAs input dummy)
-        test "List" ([] :: [Int])
-        test "Vector" (V.empty :: V.Vector Int)
-        test "Storable Vector" (VS.empty :: VS.Vector Int)
-        test "Unboxed Vector" (U.empty :: U.Vector Int)
-        test "Strict ByteString" S.empty
-        test "Lazy ByteString" L.empty
-        test "Strict Text" T.empty
-        test "Lazy Text" TL.empty
-
-    describe "Intercalate" $ do
-        let test typ dummy = describe typ $ do
-                prop "intercalate === defaultIntercalate" $ \list lists ->
-                    let seq' = fromListAs list dummy
-                        seqs = map (`fromListAs` dummy) lists
-                    in ointercalate seq' seqs @?= fromList (List.intercalate list lists)
-        test "List" ([] :: [Int])
-        test "Vector" (V.empty :: V.Vector Int)
-        test "Storable Vector" (VS.empty :: VS.Vector Int)
-        test "Unboxed Vector" (U.empty :: U.Vector Int)
-        test "Strict ByteString" S.empty
-        test "Lazy ByteString" L.empty
-        test "Strict Text" T.empty
-        test "Lazy Text" TL.empty
-
-    describe "Splitting" $ do
-        let test typ dummy = describe typ $ do
-                let fromList' = (`fromListAs` dummy)
-                let fromSepList sep = fromList' . map (fromMaybe sep)
-                prop "intercalate sep . splitSeq sep === id" $
-                    \(fromList' -> sep) ->
-                    \(mconcat . map (maybe sep fromList') -> xs) ->
-                    ointercalate sep (splitSeq sep xs) @?= xs
-                prop "splitSeq mempty xs === mempty : map singleton (otoList xs)" $
-                    \input ->
-                    splitSeq mempty (fromList' input) @?= mempty : map singleton input
-                prop "splitSeq _ mempty == [mempty]" $
-                    \(fromList' -> sep) ->
-                    splitSeq sep mempty @?= [mempty]
-                prop "intercalate (singleton sep) . splitElem sep === id" $
-                    \sep -> \(fromSepList sep -> xs) ->
-                    ointercalate (singleton sep) (splitElem sep xs) @?= xs
-                prop "length . splitElem sep === succ . length . filter (== sep)" $
-                    \sep -> \(fromSepList sep -> xs) ->
-                    olength (splitElem sep xs) @?= olength (filter (== sep) xs) + 1
-                prop "splitElem sep (replicate n sep) == replicate (n+1) mempty" $
-                    \(NonNegative n) sep ->
-                    splitElem sep (fromList' (replicate n sep)) @?= replicate (n + 1) mempty
-                prop "splitElem sep === splitWhen (== sep)" $
-                    \sep -> \(fromSepList sep -> xs) ->
-                    splitElem sep xs @?= splitWhen (== sep) xs
-                prop "splitElem sep === splitSeq (singleton sep)" $
-                    \sep -> \(fromSepList sep -> xs) ->
-                    splitElem sep xs @?= splitSeq (singleton sep) xs
-        test "List" ([] :: [Int])
-        test "Vector" (V.empty :: V.Vector Int)
-        test "Storable Vector" (VS.empty :: VS.Vector Int)
-        test "Unboxed Vector" (U.empty :: U.Vector Int)
-        test "Strict ByteString" S.empty
-        test "Lazy ByteString" L.empty
-        test "Strict Text" T.empty
-        test "Lazy Text" TL.empty
-
-    describe "Other Issues" $ do
-        it "#26 headEx on a list works" $
-            headEx (1 : filter Prelude.odd [2,4..]) @?= (1 :: Int)
-
-        it "#31 find doesn't infinitely loop on NonEmpty" $
-            find (== "a") ("a" NE.:| ["d","fgf"]) @?= Just ("a" :: String)
-
-        it "#83 head on Seq works correctly" $ do
-            headEx (Seq.fromList [1 :: Int,2,3]) @?= (1 :: Int)
-            headMay (Seq.fromList [] :: Seq.Seq Int) @?= Nothing
diff --git a/test/main.hs b/test/main.hs
deleted file mode 100644
--- a/test/main.hs
+++ /dev/null
@@ -1,1 +0,0 @@
-import Spec (main)
