diff --git a/.gitignore b/.gitignore
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,7 @@
 tests/test-error
 tests/test-fun
 tests/test-funshow
+tests/test-generic
 tests/test-io
 tests/test-most
 tests/test-operators
diff --git a/.travis.yml b/.travis.yml
--- a/.travis.yml
+++ b/.travis.yml
@@ -49,8 +49,8 @@
     env:                   GHCVER=8.6.1        CABALVER=2.4
     addons: {apt: {packages: [ghc-8.6.1,  cabal-install-2.4],  sources: hvr-ghc}}
   - ghc: '8.4'
-    env:                   GHCVER=8.4.2        CABALVER=2.2
-    addons: {apt: {packages: [ghc-8.4.2,  cabal-install-2.2],  sources: hvr-ghc}}
+    env:                   GHCVER=8.4.4        CABALVER=2.2
+    addons: {apt: {packages: [ghc-8.4.4,  cabal-install-2.2],  sources: hvr-ghc}}
   - ghc: '8.2'
     env:                   GHCVER=8.2.2        CABALVER=2.0
     addons: {apt: {packages: [ghc-8.2.2,  cabal-install-2.0],  sources: hvr-ghc}}
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@
         tests/test-error     \
         tests/test-fun       \
         tests/test-funshow   \
+        tests/test-generic   \
         tests/test-io        \
         tests/test-operators \
         tests/test-tiers     \
diff --git a/leancheck.cabal b/leancheck.cabal
--- a/leancheck.cabal
+++ b/leancheck.cabal
@@ -11,7 +11,7 @@
 -- this cabal file too complicated.  -- Rudy
 
 name:                leancheck
-version:             0.7.5
+version:             0.7.6
 synopsis:            Enumerative property-based testing
 description:
   LeanCheck is a simple enumerative property-based testing library.
@@ -70,7 +70,7 @@
 source-repository this
   type:            git
   location:        https://github.com/rudymatela/leancheck
-  tag:             v0.7.5
+  tag:             v0.7.6
 
 library
   exposed-modules: Test.LeanCheck
@@ -78,6 +78,7 @@
                  , Test.LeanCheck.Core
                  , Test.LeanCheck.Derive
                  , Test.LeanCheck.Error
+                 , Test.LeanCheck.Generic
                  , Test.LeanCheck.IO
                  , Test.LeanCheck.Tiers
                  , Test.LeanCheck.Utils
@@ -98,7 +99,9 @@
                  , Test.LeanCheck.Function.CoListable
                  , Test.LeanCheck.Function.ShowFunction
   hs-source-dirs:      src
-  build-depends:       base >= 4 && < 5, template-haskell
+  build-depends:     base >= 4 && < 5, template-haskell
+  if impl(ghc < 7.6)
+    build-depends:     ghc-prim
   default-language:    Haskell2010
 
 test-suite main
@@ -147,6 +150,16 @@
   other-modules:       Test
   hs-source-dirs:      tests
   build-depends:       base >= 4 && < 5, leancheck
+  default-language:    Haskell2010
+
+test-suite generic
+  type:                exitcode-stdio-1.0
+  main-is:             test-generic.hs
+  other-modules:       Test
+  hs-source-dirs:      tests
+  build-depends:       base >= 4 && < 5, leancheck
+  if impl(ghc < 7.6)
+    build-depends:     ghc-prim
   default-language:    Haskell2010
 
 test-suite io
diff --git a/mk/All.hs b/mk/All.hs
--- a/mk/All.hs
+++ b/mk/All.hs
@@ -4,6 +4,7 @@
   , module Test.LeanCheck.Basic
   , module Test.LeanCheck.Utils
   , module Test.LeanCheck.Tiers
+  , module Test.LeanCheck.Generic
   )
 where
 
@@ -12,3 +13,4 @@
 import Test.LeanCheck.Basic
 import Test.LeanCheck.Utils
 import Test.LeanCheck.Tiers
+import Test.LeanCheck.Generic
diff --git a/mk/Toplibs.hs b/mk/Toplibs.hs
--- a/mk/Toplibs.hs
+++ b/mk/Toplibs.hs
@@ -5,3 +5,4 @@
 import Test.LeanCheck.Utils ()
 import Test.LeanCheck.Error ()
 import Test.LeanCheck.Function ()
+import Test.LeanCheck.Generic ()
diff --git a/mk/depend.mk b/mk/depend.mk
--- a/mk/depend.mk
+++ b/mk/depend.mk
@@ -193,6 +193,7 @@
   src/Test/LeanCheck/Stats.hs \
   src/Test/LeanCheck.hs \
   src/Test/LeanCheck/IO.hs \
+  src/Test/LeanCheck/Generic.hs \
   src/Test/LeanCheck/Derive.hs \
   src/Test/LeanCheck/Core.hs \
   src/Test/LeanCheck/Basic.hs \
@@ -206,6 +207,7 @@
   src/Test/LeanCheck/Stats.hs \
   src/Test/LeanCheck.hs \
   src/Test/LeanCheck/IO.hs \
+  src/Test/LeanCheck/Generic.hs \
   src/Test/LeanCheck/Function/Show.hs \
   src/Test/LeanCheck/Function/ShowFunction.hs \
   src/Test/LeanCheck/Function.hs \
@@ -368,6 +370,9 @@
   src/Test/LeanCheck/Derive.hs \
   src/Test/LeanCheck/Core.hs \
   src/Test/LeanCheck/Basic.hs
+src/Test/LeanCheck/Generic.o: \
+  src/Test/LeanCheck/Generic.hs \
+  src/Test/LeanCheck/Core.hs
 src/Test/LeanCheck/IO.o: \
   src/Test/LeanCheck/IO.hs \
   src/Test/LeanCheck/Core.hs
@@ -488,6 +493,22 @@
 tests/test-fun: \
   tests/Test.hs \
   tests/test-fun.hs \
+  mk/toplibs
+tests/test-generic.o: \
+  tests/Test.hs \
+  tests/test-generic.hs \
+  src/Test/LeanCheck/Utils/Types.hs \
+  src/Test/LeanCheck/Utils/Operators.hs \
+  src/Test/LeanCheck/Tiers.hs \
+  src/Test/LeanCheck.hs \
+  src/Test/LeanCheck/IO.hs \
+  src/Test/LeanCheck/Generic.hs \
+  src/Test/LeanCheck/Derive.hs \
+  src/Test/LeanCheck/Core.hs \
+  src/Test/LeanCheck/Basic.hs
+tests/test-generic: \
+  tests/Test.hs \
+  tests/test-generic.hs \
   mk/toplibs
 tests/test-io.o: \
   tests/Test.hs \
diff --git a/src/Test/LeanCheck/Derive.hs b/src/Test/LeanCheck/Derive.hs
--- a/src/Test/LeanCheck/Derive.hs
+++ b/src/Test/LeanCheck/Derive.hs
@@ -8,13 +8,14 @@
 -- This module is part of LeanCheck,
 -- a simple enumerative property-based testing library.
 --
--- This is an experimental module for deriving 'Listable' instances.
---
 -- Needs GHC and Template Haskell
 -- (tested on GHC 7.4, 7.6, 7.8, 7.10, 8.0, 8.2 and 8.4).
 --
 -- If LeanCheck does not compile under later GHCs, this module is probably the
 -- culprit.
+--
+-- If you rather do this through GHC Generics, please see:
+-- "Test.LeanCheck.Generic" (experimental).
 module Test.LeanCheck.Derive
   ( deriveListable
   , deriveListableIfNeeded
@@ -52,17 +53,52 @@
 -- > instance Listable a => Listable (Stack a) where
 -- >   tiers = cons2 Stack \/ cons0 Empty
 --
+-- __Warning:__ if the values in your type need to follow a data invariant, the
+--              derived instance won't respect it.  Use this only on "free"
+--              datatypes.
+--
 -- Needs the @TemplateHaskell@ extension.
 deriveListable :: Name -> DecsQ
 deriveListable = deriveListableX True False
 
--- | Same as 'deriveListable' but does not warn when instance already exists
---   ('deriveListable' is preferable).
+-- | Same as 'deriveListable' but does not warn when the requested instance
+--   already exists.  The function 'deriveListable' is preferable in most
+--   situations.
 deriveListableIfNeeded :: Name -> DecsQ
 deriveListableIfNeeded = deriveListableX False False
 
 -- | Derives a 'Listable' instance for a given type 'Name'
 --   cascading derivation of type arguments as well.
+--
+-- Consider the following series of datatypes:
+--
+-- > data Position = CEO | Manager | Programmer
+-- >
+-- > data Person = Person
+-- >             { name :: String
+-- >             , age :: Int
+-- >             , position :: Position
+-- >             }
+-- >
+-- > data Company = Company
+-- >              { name :: String
+-- >              , employees :: [Person]
+-- >              }
+--
+-- Writing
+--
+-- > deriveListableCascading ''Company
+--
+-- will automatically derive the following three 'Listable' instances:
+--
+-- > instance Listable Position where
+-- >   tiers = cons0 CEO \/ cons0 Manager \/ cons0 Programmer
+-- >
+-- > instance Listable Person where
+-- >   tiers = cons3 Person
+-- >
+-- > instance Listable Company where
+-- >   tiers = cons2 Company
 deriveListableCascading :: Name -> DecsQ
 deriveListableCascading = deriveListableX True True
 
@@ -104,6 +140,11 @@
 --   'tiers':
 --
 -- > consN C1 \/ consN C2 \/ ... \/ consN CN
+--
+-- This function can be used in the definition of 'Listable' instances:
+--
+-- > instance Listable MyType where
+-- >   tiers = $(deriveTiers)
 deriveTiers :: Name -> ExpQ
 deriveTiers t = conse =<< typeConstructors t
   where
diff --git a/src/Test/LeanCheck/Generic.hs b/src/Test/LeanCheck/Generic.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/LeanCheck/Generic.hs
@@ -0,0 +1,65 @@
+{-# LANGUAGE FlexibleContexts, TypeOperators #-}
+-- |
+-- Module      : Test.LeanCheck.Generic
+-- Copyright   : (c) 2018 Rudy Matela
+-- License     : 3-Clause BSD  (see the file LICENSE)
+-- Maintainer  : Rudy Matela <rudy@matela.com.br>
+--
+-- This module is part of LeanCheck,
+-- a simple enumerative property-based testing library.
+--
+-- This is an experimental module for deriving 'Listable' instances through
+-- GHC's generic.
+--
+-- If you rather do this through Template Haskell please see:
+-- "Test.LeanCheck.Derive".
+module Test.LeanCheck.Generic
+  ( genericList
+  , genericTiers
+  )
+where
+
+import GHC.Generics
+import Test.LeanCheck.Core
+
+-- | A generic implementation of 'list' for instances of 'Generic'.
+--
+-- Use it to define your 'Listable' instances like so:
+--
+-- > instance Listable MyType where
+-- >   list = genericList
+--
+-- Consider using 'genericTiers' instead of this
+-- (unless you know what you're doing).
+genericList :: (Generic a, Listable' (Rep a)) => [a]
+genericList = concat genericTiers
+
+-- | A generic implementation of 'tiers' for instances of 'Generic'.
+--
+-- Use it to define your 'Listable' instances like so:
+--
+-- > instance Listable MyType where
+-- >   tiers = genericTiers
+genericTiers :: (Generic a, Listable' (Rep a)) => [[a]]
+genericTiers = mapT to tiers'
+
+class Listable' f where
+  tiers' :: [[f p]]
+
+instance Listable' V1 where
+  tiers' = undefined
+
+instance Listable' U1 where
+  tiers' = [[U1]]
+
+instance Listable c => Listable' (K1 i c) where
+  tiers' = mapT K1 tiers
+
+instance (Listable' a, Listable' b) => Listable' (a :+: b) where
+  tiers' = mapT L1 tiers' \/ mapT R1 tiers'
+
+instance (Listable' a, Listable' b) => Listable' (a :*: b) where
+  tiers' = productWith (:*:) tiers' tiers'
+
+instance Listable' f => Listable' (M1 i c f) where
+  tiers' = mapT M1 tiers'
diff --git a/tests/test-generic.hs b/tests/test-generic.hs
new file mode 100644
--- /dev/null
+++ b/tests/test-generic.hs
@@ -0,0 +1,65 @@
+-- Copyright (c) 2015-2018 Rudy Matela.
+-- Distributed under the 3-Clause BSD licence (see the file LICENSE).
+{-# LANGUAGE DeriveGeneric, StandaloneDeriving #-}
+import Test
+import Test.LeanCheck
+import Test.LeanCheck.Generic
+import System.Exit (exitFailure)
+import Data.List (elemIndices,sort)
+import Test.LeanCheck.Utils.Operators
+import GHC.Generics (Generic)
+
+data D0       = D0                    deriving (Eq, Show, Generic)
+data D1 a     = D1 a                  deriving (Eq, Show, Generic)
+data D2 a b   = D2 a b                deriving (Eq, Show, Generic)
+data D3 a b c = D3 a b c              deriving (Eq, Show, Generic)
+data C1 a     =           C11 a | C10 deriving (Eq, Show, Generic)
+data C2 a b   = C22 a b | C21 a | C20 deriving (Eq, Show, Generic)
+data I a b    = a :+ b                deriving (Eq, Show, Generic)
+
+instance Listable D0                   where tiers = genericTiers
+
+instance Listable a => Listable (D1 a) where tiers = genericTiers
+
+instance (Listable a, Listable b)
+      => Listable (D2 a b)             where tiers = genericTiers
+
+instance (Listable a, Listable b, Listable c)
+      => Listable (D3 a b c)           where tiers = genericTiers
+
+instance Listable a => Listable (C1 a) where tiers = genericTiers
+
+instance (Listable a, Listable b)
+      => Listable (C2 a b)             where tiers = genericTiers
+
+instance (Listable a, Listable b)
+      => Listable (I a b)              where tiers = genericTiers
+
+main :: IO ()
+main =
+  case elemIndices False (tests 100) of
+    [] -> putStrLn "Tests passed!"
+    is -> do putStrLn ("Failed tests:" ++ show is)
+             exitFailure
+
+tests n =
+  [ True
+
+  , map unD0 list =| n |= list
+  , map unD1 list =| n |= (list :: [Int])
+  , map unD2 list =| n |= (list :: [(Int,Int)])
+  , map unD3 list =| n |= (list :: [(Int,Int,Int)])
+
+  , map unD1 list == (list :: [()])
+  , map unD2 list == (list :: [((),())])
+  , map unD3 list == (list :: [((),(),())])
+
+  , map unD1 list == (list :: [Bool])
+  , map unD2 list == (list :: [(Bool,Bool)])
+  , map unD3 list == (list :: [(Bool,Bool,Bool)])
+  ]
+  where
+  unD0 (D0)       = ()
+  unD1 (D1 x)     = (x)
+  unD2 (D2 x y)   = (x,y)
+  unD3 (D3 x y z) = (x,y,z)
