diff --git a/catamorphism.cabal b/catamorphism.cabal
--- a/catamorphism.cabal
+++ b/catamorphism.cabal
@@ -1,5 +1,5 @@
 name:                catamorphism
-version:             0.6.0.0
+version:             0.6.1.0
 synopsis:            A package exposing a helper function for generating catamorphisms.
 description:         A package exposing a helper function for generating catamorphisms.
 homepage:            https://github.com/frerich/catamorphism
@@ -20,7 +20,16 @@
 
 library
   exposed-modules:     Data.Morphism.Cata
-  build-depends:       base >=4.6 && <4.11, template-haskell >=2.8 && <2.13
+  build-depends:       base >=4.6 && <4.12, template-haskell >=2.8 && <2.14
   hs-source-dirs:      src
   default-language:    Haskell2010
   ghc-options:         -Wall
+
+test-suite spec
+  type:                exitcode-stdio-1.0
+  main-is:             Tests.hs
+  hs-source-dirs:      test
+  ghc-options:         -Wall
+  build-depends:       base, catamorphism, hspec
+  other-modules:       Data.Morphism.CataSpec
+  default-language:    Haskell2010
diff --git a/src/Data/Morphism/Cata.hs b/src/Data/Morphism/Cata.hs
--- a/src/Data/Morphism/Cata.hs
+++ b/src/Data/Morphism/Cata.hs
@@ -73,7 +73,12 @@
 import Control.Monad (forM, replicateM)
 
 import Data.Char (toLower)
+-- The prelude exports (<$>) in base 4.8.0 and later, so don't include
+-- Data.Functor to avoid compiler warnings about unneeded imports.
+#if MIN_VERSION_base(4,8,0)
+#else
 import Data.Functor ((<$>))
+#endif
 
 import Language.Haskell.TH
 import Language.Haskell.TH.Syntax (mkNameG, NameSpace(TcClsName))
diff --git a/test/Data/Morphism/CataSpec.hs b/test/Data/Morphism/CataSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Data/Morphism/CataSpec.hs
@@ -0,0 +1,95 @@
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE TemplateHaskell #-}
+
+-- GHC 7.10 seems to require KindSignatures for the polymorph folds defined
+-- below.
+#if __GLASGOW_HASKELL__ >= 710
+{-# LANGUAGE KindSignatures #-}
+#endif
+
+module Data.Morphism.CataSpec (main, spec) where
+
+import Test.Hspec
+import Data.Morphism.Cata
+
+import Data.Bool (bool)
+import Data.Maybe (maybe)
+import Data.Either (either)
+
+data Unit = Unit
+data Binary = Zero | One
+data PolymorphSum a = PolymorphSum a
+data PolymorphProduct a b = PolymorphProduct a b
+data RegularRecursive a = Cons a (RegularRecursive a) | Empty
+
+$(makeCata defaultOptions ''Unit)
+$(makeCata defaultOptions ''Binary)
+$(makeCata defaultOptions ''PolymorphSum)
+$(makeCata defaultOptions ''PolymorphProduct)
+$(makeCata defaultOptions ''RegularRecursive)
+$(makeCata defaultOptions { cataName = "binaryFold" } ''Binary)
+
+$(makeCata defaultOptions { cataName = "bool'" } ''Bool)
+$(makeCata defaultOptions { cataName = "maybe'" } ''Maybe)
+$(makeCata defaultOptions { cataName = "either'" } ''Either)
+$(makeCata defaultOptions { cataName = "foldr'" } ''[])
+
+-- `main` is here so that this module can be run from GHCi on its own.  It is
+-- not needed for automatic spec discovery.
+main :: IO ()
+main = hspec spec
+
+spec :: Spec
+spec = do
+  describe "type support" $ do
+    it "handles Unit" $ do
+      unit True Unit `shouldBe` True
+      unit "foo" Unit `shouldBe` "foo"
+
+    it "handles simple sum types" $ do
+      binary 'z' 'o' Zero `shouldBe` 'z'
+      binary 'z' 'o' One `shouldBe` 'o'
+
+    it "handles polymorph sum types" $ do
+      polymorphSum show (PolymorphSum True) `shouldBe` "True"
+      polymorphSum length (PolymorphSum "Frerich") `shouldBe` 7
+
+    it "handles polymorph product types" $ do
+      let fn = (\b x -> show (if b then x + 1 else x - 1)) :: Bool -> Int -> String
+      polymorphProduct fn (PolymorphProduct True 99) `shouldBe` "100"
+      polymorphProduct fn (PolymorphProduct False 88) `shouldBe` "87"
+
+    it "handles regular recursive types" $ do
+      let length' = regularRecursive (\_ acc -> acc + 1) 0 :: RegularRecursive a -> Int
+      length' Empty `shouldBe` 0
+      length' (Cons () (Cons () (Cons () Empty))) `shouldBe` 3
+      length' (Cons 'a' (Cons 'b' Empty)) `shouldBe` 2
+
+  describe "custom options" $
+    it "allows customizing the function name" $ do
+      binaryFold 'z' 'o' Zero `shouldBe` 'z'
+      binaryFold 'z' 'o' One `shouldBe` 'o'
+
+  describe "equivalence" $ do
+    let checkBinaryFn f g a b x = f a b x `shouldBe` g a b x
+
+    it "can be used to define bool" $ do
+      let check = checkBinaryFn bool bool' "false" "true"
+      check False
+      check True
+
+    it "can be used to define maybe" $ do
+      let check = checkBinaryFn maybe maybe' "<empty>" (++ "!!!")
+      check Nothing
+      check (Just "Hello")
+
+    it "can be used to define either" $ do
+      let check = checkBinaryFn either either' show (++ "!!!")
+      check (Left True)
+      check (Right "Either")
+
+    it "can be used to define foldr" $ do
+      -- Well, we can get 'foldr', but flipped.
+      let check = checkBinaryFn (flip foldr) foldr' (0 :: Int) (\_ acc -> acc + 1)
+      check []
+      check "Frobnicate"
diff --git a/test/Tests.hs b/test/Tests.hs
new file mode 100644
--- /dev/null
+++ b/test/Tests.hs
@@ -0,0 +1,1 @@
+{-# OPTIONS_GHC -F -pgmF hspec-discover #-}
