diff --git a/default.nix b/default.nix
--- a/default.nix
+++ b/default.nix
@@ -1,28 +1,63 @@
-# To pin to a specific version of nixpkgs, you can substitute <nixpkgs> with:
-# `(builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/<nixpkgs_commit_hash>.tar.gz")`
-{ pkgs ? import <nixpkgs> {} }: pkgs.haskellPackages.developPackage
-  { root = ./.;
-    overrides = self: super:
-      { # Don't run a package's test suite
-        # foo = pkgs.haskell.lib.dontCheck pkgs.haskellPackages.foo;
-        #
-        # Don't enforce package's version constraints
-        # bar = pkgs.haskell.lib.doJailbreak pkgs.haskellPackages.bar;
-        #
-        # To discover more functions that can be used to modify haskell
-        # packages, run "nix-repl", type "pkgs.haskell.lib.", then hit
-        # <TAB> to get a tab-completed list of functions.
-      };
-    source-overrides =
-      { # Use a specific hackage version
-        # io-streams = "1.4.0.0";
-        #
-        # Use a particular commit from github
-        # text = pkgs.fetchFromGitHub
-        #   { owner = "haskell";
-        #     repo = "text";
-        #     rev = "ab90c65cdb7cd5bcbd739843b98bb5da515c8bce";
-        #     sha256 = "0phar79fky4yzv4hq28py18i4iw779gp5n327xx76mrj7yj87id3";
-        #   };
-      };
-  }
+{ compiler ? "ghc881"
+, rev      ? "c4f97342ba8ac84def72328616dd05d005bb4715"
+, sha256   ? "1p2gbisib2jrz4r9b5vzfvmirgmz9sr2ksalngaw908vvg9hsvai"
+, pkgs     ?
+    import (builtins.fetchTarball {
+      url    = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
+      inherit sha256; }) {
+      config.allowBroken = false;
+      config.allowUnfree = true;
+    }
+}:
+let gitignoreSrc = import (pkgs.fetchFromGitHub {
+      owner = "hercules-ci";
+      repo = "gitignore";
+      rev = "2ced4519f865341adcb143c5d668f955a2cb997f";
+      sha256 = "0fc5bgv9syfcblp23y05kkfnpgh3gssz6vn24frs8dzw39algk2z";
+    }) {};
+
+in
+pkgs.haskell.packages.${compiler}.developPackage {
+  name = builtins.baseNameOf ./.;
+  root = gitignoreSrc.gitignoreSource ./.;
+
+  overrides = self: super: with pkgs.haskell.lib; {
+    # Don't run a package's test suite
+    # foo = dontCheck super.foo;
+    #
+    # Don't enforce package's version constraints
+    # bar = doJailbreak super.bar;
+    #
+    # Get a specific hackage version straight from hackage. Unlike the above
+    # callHackage approach, this will always succeed if the version is on
+    # hackage. The downside is that you have to specify the hash manually.
+    # aeson = callHackageDirect {
+    #   pkg = "aeson";
+    #   ver = "1.4.2.0";
+    #   sha256 = "0qcczw3l596knj9s4ha07wjspd9wkva0jv4734sv3z3vdad5piqh";
+    # } {};
+    #
+    # To discover more functions that can be used to modify haskell
+    # packages, run "nix-repl", type "pkgs.haskell.lib.", then hit
+    # <TAB> to get a tab-completed list of functions.
+  };
+  source-overrides = {
+    # Use a specific hackage version using callHackage. Only works if the
+    # version you want is in the version of all-cabal-hashes that you have.
+    # bytestring = "0.10.8.1";
+    #
+    # Use a particular commit from github
+    # parsec = pkgs.fetchFromGitHub
+    #   { owner = "hvr";
+    #     repo = "parsec";
+    #     rev = "c22d391c046ef075a6c771d05c612505ec2cd0c3";
+    #     sha256 = "0phar79fky4yzv4hq28py18i4iw779gp5n327xx76mrj7yj87id3";
+    #   };
+  };
+  modifier = drv: pkgs.haskell.lib.overrideCabal drv (attrs: {
+    buildTools = (attrs.buildTools or []) ++ [
+      pkgs.haskell.packages.${compiler}.cabal-install
+      pkgs.haskell.packages.${compiler}.ghcid
+    ];
+  });
+}
diff --git a/fake.cabal b/fake.cabal
--- a/fake.cabal
+++ b/fake.cabal
@@ -1,5 +1,5 @@
 name:                fake
-version:             0.1.1.3
+version:             0.1.2
 synopsis:            Randomly generated fake data
 description:         QuickCheck generates completely random data for the
                      purposes of test and catching corner cases.  The fake
@@ -21,8 +21,10 @@
   GHC==8.0.2,
   GHC==8.2.2,
   GHC==8.4.4,
-  GHC==8.6.5,
-  GHC==8.8.2
+  GHC==8.6.3,
+  GHC==8.8.3,
+  GHC==8.10.1,
+  GHC==9.0.1
 
 extra-source-files:
   default.nix
@@ -52,12 +54,12 @@
   other-modules:    Fake.Types
 
   build-depends:
-    base         >= 4.6 && < 4.14,
+    base         >= 4.6 && < 4.16,
     containers   >= 0.5 && < 0.7,
     generics-sop >= 0.2 && < 0.6,
-    random       >= 1.1 && < 1.2,
+    random       >= 1.1 && < 1.3,
     text         >= 1.2 && < 1.3,
-    time         >= 1.4 && < 1.10
+    time         >= 1.4 && < 1.12
 
   ghc-options: -Wall
   hs-source-dirs:      src
@@ -78,6 +80,7 @@
   build-depends:
     base,
     hspec >= 2.4 && < 2.8,
+    lens >= 4.18.1 && < 5.1,
     random,
     text,
     time
diff --git a/src/Fake/Cover.hs b/src/Fake/Cover.hs
--- a/src/Fake/Cover.hs
+++ b/src/Fake/Cover.hs
@@ -30,6 +30,8 @@
   ( gcover
   , Coverage(..)
   , Cover(..)
+  , bindCover
+  , (&>>=)
   ) where
 
 ------------------------------------------------------------------------------
@@ -57,6 +59,29 @@
     alen = length as
     blen = length bs
     newlen = max alen blen
+
+------------------------------------------------------------------------------
+-- | In some situations you don't have the ability to modify a data structure
+-- and need to define different Cover instances for different fields that have
+-- the same type.  In these situations, instead of implementing the gcover
+-- logic by hand, you could alternatively use gcover to generate stock
+-- coverage values and then go back and replace the necessary fields with more
+-- appropriate generators.  This bind-like operation provides an easy way to
+-- do that.
+bindCover :: Coverage a -> (a -> FGen b) -> Coverage b
+bindCover (Coverage gens) f = Coverage $ map (>>= f) gens
+
+------------------------------------------------------------------------------
+-- | Convenience infix operator for bindCover.
+--
+-- @
+-- instance Cover Foo where
+--   cover = gcover
+--     &>>= fooField %%~ (\_ -> fakeFooField)
+-- @
+(&>>=) :: Coverage a -> (a -> FGen b) -> Coverage b
+(&>>=) = bindCover
+infixl 1 &>>=
 
 instance Alternative Coverage where
   empty = Coverage empty
diff --git a/src/Fake/Provider/Person/EN_US.hs b/src/Fake/Provider/Person/EN_US.hs
--- a/src/Fake/Provider/Person/EN_US.hs
+++ b/src/Fake/Provider/Person/EN_US.hs
@@ -2205,6 +2205,7 @@
 -- | List of the 1000 most common U.S. surnames and the number of people with
 -- that name.  This is from a dataset of 269762087 names from the 2000 U.S.
 -- Census.
+lastNameList :: [(Int, Text)]
 lastNameList = lastNameList00
             ++ lastNameList01
             ++ lastNameList02
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -1,9 +1,12 @@
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-{-# LANGUAGE DeriveGeneric        #-}
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TemplateHaskell #-}
 
 module Main where
 
 ------------------------------------------------------------------------------
+import           Control.Lens hiding (elements)
 import           Data.Foldable
 import           Data.Time
 import           GHC.Generics
@@ -18,40 +21,6 @@
 import           Fake.Types
 ------------------------------------------------------------------------------
 
-testFake :: FGen a -> a
-testFake (MkFGen f) = f $ mkStdGen 5
-
-tc :: Coverage a -> [a]
-tc = testFake . sequence . unCoverage
-
-------------------------------------------------------------------------------
-main :: IO ()
-main = hspec $ do
-    describe "Fake.Cover" $ do
-      it "Maybe Int" $
-        tc gcover `shouldBe` [Nothing, Just (94 :: Int)]
-      it "Either Int Char" $
-        tc gcover `shouldBe` [Left (53 :: Int), Right 't']
-      it "(Maybe Int, ThreePhonetic)" $
-        tc gcover `shouldBe`
-        [(Nothing,Alpha),(Just (84 :: Int),Bravo),(Nothing,Charlie)]
-      it "(Either ThreePhonetic Four)" $
-        tc gcover `shouldBe`
-        [ Left Alpha
-        , Left Bravo
-        , Left Charlie
-        , Right (MOne 96)
-        , Right (MTwo 'k')
-        , Right (MThree 12)
-        , Right (MFour 'v')
-        ]
-      -- Since Person contains one Maybe field, cover should generate two values
-      it "Person" $
-        tc cover `shouldBe`
-        [ Person "Opal" "Clark" (fromGregorian 1958 10 12) Nothing
-        , Person "Katherine" "Oneill" (fromGregorian 1966 07 21) (Just "123-45-6789")
-        ]
-
 instance Cover Int where
     cover = Coverage [fakeInt 0 100]
 
@@ -70,8 +39,13 @@
           | MFour Char
   deriving (Eq,Ord,Show,Generic)
 
+makePrisms ''Four
+
 instance Cover Four where
     cover = gcover
+      -- Use gcover for the majority of the generation, then tweak one field to
+      -- be a different distribution.
+      &>>= _MFour %%~ (\_ -> fakeEnumFromTo 'A' 'F')
 
 birthdayCoverage :: Coverage Day
 birthdayCoverage = fromGregorian
@@ -101,3 +75,65 @@
     <*> fmap unpack (Coverage [unSingleWord <$> lastName])
     <*> birthdayCoverage
     <*> asum [ pure Nothing, Just <$> ssnCoverage ]
+
+
+testFake :: FGen a -> a
+testFake (MkFGen f) = f $ mkStdGen 5
+
+tc :: Coverage a -> [a]
+tc = testFake . sequence . unCoverage
+
+------------------------------------------------------------------------------
+main :: IO ()
+main = hspec $ do
+    describe "Fake.Cover" $ do
+
+#if MIN_VERSION_random(1,2,0)
+      it "Maybe Int" $
+        tc gcover `shouldBe` [Nothing, Just (37 :: Int)]
+      it "Either Int Char" $
+        tc gcover `shouldBe` [Left (8 :: Int), Right 'f']
+      it "(Maybe Int, ThreePhonetic)" $
+        tc gcover `shouldBe`
+        [(Nothing,Alpha),(Just (26 :: Int),Bravo),(Nothing,Charlie)]
+      it "(Either ThreePhonetic Four)" $
+        tc gcover `shouldBe`
+        [ Left Alpha
+        , Left Bravo
+        , Left Charlie
+        , Right (MOne 39)
+        , Right (MTwo 'u')
+        , Right (MThree 17)
+        , Right (MFour 'C')
+        ]
+      -- Since Person contains one Maybe field, cover should generate two values
+      it "Person" $
+        tc cover `shouldBe`
+        [ Person "Jaylen" "Massey" (fromGregorian 1967 1 21) Nothing
+        , Person "Timothy" "Garcia" (fromGregorian 2007 4 18) (Just "000-00-0000")
+        ]
+#else
+      it "Maybe Int" $
+        tc gcover `shouldBe` [Nothing, Just (94 :: Int)]
+      it "Either Int Char" $
+        tc gcover `shouldBe` [Left (53 :: Int), Right 't']
+      it "(Maybe Int, ThreePhonetic)" $
+        tc gcover `shouldBe`
+        [(Nothing,Alpha),(Just (84 :: Int),Bravo),(Nothing,Charlie)]
+      it "(Either ThreePhonetic Four)" $
+        tc gcover `shouldBe`
+        [ Left Alpha
+        , Left Bravo
+        , Left Charlie
+        , Right (MOne 32)
+        , Right (MTwo 'j')
+        , Right (MThree 17)
+        , Right (MFour 'B')
+        ]
+      -- Since Person contains one Maybe field, cover should generate two values
+      it "Person" $
+        tc cover `shouldBe`
+        [ Person "Opal" "Clark" (fromGregorian 1958 10 12) Nothing
+        , Person "Katherine" "Oneill" (fromGregorian 1966 07 21) (Just "123-45-6789")
+        ]
+#endif
