diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,11 @@
+### 0.6.4 [2023.08.06]
+* Support building with `template-haskell-2.21.*` (GHC 9.8).
+* The Template Haskell machinery now uses `TemplateHaskellQuotes` when building
+  with GHC 8.0+ instead of manually constructing each Template Haskell `Name`.
+  A consequence of this is that `deriving-compat` will now build with GHC 9.8,
+  as `TemplateHaskellQuotes` abstracts over some internal Template Haskell
+  changes introduced in 9.8.
+
 ### 0.6.3 [2023.02.27]
 * Support `th-abstraction-0.5.*`.
 
diff --git a/deriving-compat.cabal b/deriving-compat.cabal
--- a/deriving-compat.cabal
+++ b/deriving-compat.cabal
@@ -1,5 +1,5 @@
 name:                deriving-compat
-version:             0.6.3
+version:             0.6.4
 synopsis:            Backports of GHC deriving extensions
 description:         @deriving-compat@ provides Template Haskell functions that
                      mimic @deriving@ extensions that were introduced or modified
@@ -91,9 +91,9 @@
                    , GHC == 8.8.4
                    , GHC == 8.10.7
                    , GHC == 9.0.2
-                   , GHC == 9.2.6
-                   , GHC == 9.4.4
-                   , GHC == 9.6.1
+                   , GHC == 9.2.8
+                   , GHC == 9.4.5
+                   , GHC == 9.6.2
 cabal-version:       >=1.10
 
 source-repository head
@@ -139,19 +139,19 @@
                        Text.Read.Deriving.Internal
                        Text.Show.Deriving
                        Text.Show.Deriving.Internal
-  other-modules:       Paths_deriving_compat
   build-depends:       containers          >= 0.1   && < 0.7
                      , ghc-prim
-                     , th-abstraction      >= 0.4   && < 0.6
+                     , th-abstraction      >= 0.4   && < 0.7
 
   if flag(base-4-9)
     build-depends:     base                >= 4.9   && < 5
     cpp-options:       "-DNEW_FUNCTOR_CLASSES"
   else
     build-depends:     base                >= 4.3   && < 4.9
+                     , semigroups          >= 0.6   && < 0.21
 
   if flag(template-haskell-2-11)
-    build-depends:     template-haskell    >= 2.11  && < 2.21
+    build-depends:     template-haskell    >= 2.11  && < 2.22
                      , ghc-boot-th
   else
     build-depends:     template-haskell    >= 2.5   && < 2.11
@@ -190,7 +190,7 @@
                      , hspec               >= 1.8
                      , QuickCheck          >= 2      && < 3
                      , tagged              >= 0.7    && < 1
-                     , template-haskell    >= 2.5    && < 2.21
+                     , template-haskell    >= 2.5    && < 2.22
                      , void                >= 0.5.10 && < 1
   build-tool-depends:  hspec-discover:hspec-discover >= 1.8
 
diff --git a/src/Data/Bounded/Deriving/Internal.hs b/src/Data/Bounded/Deriving/Internal.hs
--- a/src/Data/Bounded/Deriving/Internal.hs
+++ b/src/Data/Bounded/Deriving/Internal.hs
@@ -20,6 +20,8 @@
     ) where
 
 import Data.Deriving.Internal
+import qualified Data.List.NonEmpty as NE
+import Data.List.NonEmpty (NonEmpty(..))
 
 import Language.Haskell.TH.Datatype
 import Language.Haskell.TH.Lib
@@ -90,7 +92,7 @@
 -- given constructors. All constructors must be from the same type.
 makeBoundedFunForCons :: BoundedFun -> Name -> [ConstructorInfo] -> Q Exp
 makeBoundedFunForCons _  _      [] = noConstructorsError
-makeBoundedFunForCons bf tyName cons
+makeBoundedFunForCons bf tyName (con:cons')
     | not (isProduct || isEnumeration)
     = enumerationOrProductError $ nameBase tyName
     | isEnumeration
@@ -102,9 +104,12 @@
     isProduct     = isProductType cons
     isEnumeration = isEnumerationType cons
 
+    cons :: NonEmpty ConstructorInfo
+    cons = con :| cons'
+
     con1, conN :: Q Exp
-    con1 = conE $ constructorName $ head cons
-    conN = conE $ constructorName $ last cons
+    con1 = conE $ constructorName con
+    conN = conE $ constructorName $ NE.last cons
 
     pickCon :: Q Exp
     pickCon = case bf of
@@ -114,7 +119,7 @@
     pickConApp :: Q Exp
     pickConApp = appsE
                $ pickCon
-               : map varE (replicate (conArity $ head cons) (boundedFunName bf))
+               : map varE (replicate (conArity con) (boundedFunName bf))
 
 -------------------------------------------------------------------------------
 -- Class-specific constants
diff --git a/src/Data/Deriving/Internal.hs b/src/Data/Deriving/Internal.hs
--- a/src/Data/Deriving/Internal.hs
+++ b/src/Data/Deriving/Internal.hs
@@ -3,12 +3,10 @@
 {-# LANGUAGE GADTs #-}
 {-# LANGUAGE MagicHash #-}
 
-#if !(MIN_VERSION_base(4,9,0))
-# if __GLASGOW_HASKELL__ >= 800
+#if __GLASGOW_HASKELL__ >= 800
 {-# LANGUAGE TemplateHaskellQuotes #-}
-# else
+#else
 {-# LANGUAGE TemplateHaskell #-}
-# endif
 #endif
 
 {-|
@@ -25,40 +23,71 @@
 -}
 module Data.Deriving.Internal where
 
-import qualified Control.Applicative as App (liftA2)
+import qualified Control.Applicative as App
 import           Control.Monad (when, unless)
 
-import           Data.Foldable (foldr')
-#if !(MIN_VERSION_base(4,9,0))
-import           Data.Functor.Classes (Eq1(..), Ord1(..), Read1(..), Show1(..))
-# if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
-import           Data.Functor.Classes (Eq2(..), Ord2(..), Read2(..), Show2(..))
-# endif
+import qualified Data.Foldable as F
+import           Data.Functor.Classes
+                   ( Eq1(..), Ord1(..), Read1(..), Show1(..)
+#if MIN_VERSION_base(4,10,0)
+                   , liftReadListPrecDefault
 #endif
+                   )
+#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
+import           Data.Functor.Classes
+                   ( Eq2(..), Ord2(..), Read2(..), Show2(..)
+#if MIN_VERSION_base(4,10,0)
+                   , liftReadListPrec2Default
+#endif
+                   )
+#endif
 import qualified Data.List as List
+import           Data.List.NonEmpty (NonEmpty(..))
 import qualified Data.Map as Map
 import           Data.Map (Map)
 import           Data.Maybe
+import           Data.Monoid (Dual(..), Endo(..))
 import qualified Data.Set as Set
 import           Data.Set (Set)
 import qualified Data.Traversable as T
 
-import           Text.ParserCombinators.ReadPrec (ReadPrec)
+import           GHC.Arr (Ix(..))
+import           GHC.Base (getTag)
+import           GHC.Exts
+import           GHC.Read (choose, list, paren)
+import           GHC.Show (showSpace)
+
+import           Text.ParserCombinators.ReadPrec
+                   ( ReadPrec, (+++), pfail, prec, readPrec_to_S, readS_to_Prec
+                   , reset, step
+                   )
+import           Text.Read (Read(..), parens, readListPrecDefault)
 import qualified Text.Read.Lex as L
+import           Text.Show (showListWith)
 
 #if MIN_VERSION_base(4,7,0)
 import           GHC.Read (expectP)
 #else
 import           GHC.Read (lexP)
-
-import           Text.Read (pfail)
 import           Text.Read.Lex (Lexeme)
 #endif
 
-#if MIN_VERSION_ghc_prim(0,3,1)
-import           GHC.Prim (Int#, tagToEnum#)
+#if !(MIN_VERSION_base(4,8,0))
+import           Control.Applicative (Applicative(..))
+import           Data.Foldable (Foldable(..))
+import           Data.Functor (Functor(..))
+import           Data.Monoid (Monoid(..))
+import           Data.Traversable (Traversable(..))
 #endif
 
+#if MIN_VERSION_base(4,10,0)
+import           GHC.Show (showCommaSpace)
+#endif
+
+#if MIN_VERSION_base(4,11,0)
+import           GHC.Read (readField, readSymField)
+#endif
+
 #if defined(MIN_VERSION_ghc_boot_th)
 import           GHC.Lexeme (startsConSym, startsVarSym)
 #else
@@ -77,11 +106,6 @@
 import           Data.Foldable ()
 import           Data.Traversable ()
 
-#ifndef CURRENT_PACKAGE_KEY
-import           Data.Version (showVersion)
-import           Paths_deriving_compat (version)
-#endif
-
 -------------------------------------------------------------------------------
 -- Expanding type synonyms
 -------------------------------------------------------------------------------
@@ -97,7 +121,7 @@
 substNameWithKind n k = applySubstitutionKind (Map.singleton n k)
 
 substNamesWithKindStar :: [Name] -> Type -> Type
-substNamesWithKindStar ns t = foldr' (flip substNameWithKind starK) t ns
+substNamesWithKindStar ns t = F.foldr' (flip substNameWithKind starK) t ns
 
 -------------------------------------------------------------------------------
 -- Via
@@ -308,7 +332,7 @@
     -- eta-reduction check might get tripped up over type variables in a
     -- synonym that are actually dropped.
     -- (See GHC Trac #11416 for a scenario where this actually happened.)
-    varTysExp <- mapM resolveTypeSynonyms varTysOrig
+    varTysExp <- T.mapM resolveTypeSynonyms varTysOrig
 
     let remainingLength :: Int
         remainingLength = length varTysOrig - arity cRep
@@ -680,14 +704,11 @@
 interleave (a1:a1s) (a2:a2s) = a1:a2:interleave a1s a2s
 interleave _        _        = []
 
-#if MIN_VERSION_ghc_prim(0,3,1)
-isTrue# :: Int# -> Bool
-isTrue# x = tagToEnum# x
-#else
+#if !(MIN_VERSION_ghc_prim(0,3,1))
 isTrue# :: Bool -> Bool
 isTrue# x = x
-#endif
 {-# INLINE isTrue# #-}
+#endif
 
 -- filterByList, filterByLists, and partitionByList taken from GHC (BSD3-licensed)
 
@@ -804,15 +825,14 @@
 conArity (ConstructorInfo { constructorFields = tys }) = length tys
 
 -- | Returns 'True' if it's a datatype with exactly one, non-existential constructor.
-isProductType :: [ConstructorInfo] -> Bool
-isProductType [con] = null (constructorVars con)
-isProductType _     = False
+isProductType :: NonEmpty ConstructorInfo -> Bool
+isProductType (con :| []) = null (constructorVars con)
+isProductType _           = False
 
 -- | Returns 'True' if it's a datatype with one or more nullary, non-GADT
 -- constructors.
-isEnumerationType :: [ConstructorInfo] -> Bool
-isEnumerationType cons@(_:_) = all (App.liftA2 (&&) isNullaryCon isVanillaCon) cons
-isEnumerationType _          = False
+isEnumerationType :: NonEmpty ConstructorInfo -> Bool
+isEnumerationType cons = F.all (App.liftA2 (&&) isNullaryCon isVanillaCon) cons
 
 -- | Returns 'False' if we're dealing with existential quantification or GADTs.
 isVanillaCon :: ConstructorInfo -> Bool
@@ -821,7 +841,7 @@
 
 -- | Generate a list of fresh names with a common prefix, and numbered suffixes.
 newNameList :: String -> Int -> Q [Name]
-newNameList prefix n = mapM (newName . (prefix ++) . show) [1..n]
+newNameList prefix n = T.mapM (newName . (prefix ++) . show) [1..n]
 
 -- | Extracts the kind from a TyVarBndr.
 tvbKind :: TyVarBndr_ flag -> Kind
@@ -1209,395 +1229,355 @@
 #endif
 
 -------------------------------------------------------------------------------
--- Manually quoted names
+-- Quoted names
 -------------------------------------------------------------------------------
 
--- By manually generating these names we avoid needing to use the
--- TemplateHaskell language extension when compiling the deriving-compat library.
--- This allows the library to be used in stage1 cross-compilers.
-
-derivingCompatPackageKey :: String
-#ifdef CURRENT_PACKAGE_KEY
-derivingCompatPackageKey = CURRENT_PACKAGE_KEY
-#else
-derivingCompatPackageKey = "deriving-compat-" ++ showVersion version
-#endif
-
-gHC_IX :: String
-#if MIN_VERSION_base(4,14,0)
-gHC_IX = "GHC.Ix"
-#else
-gHC_IX = "GHC.Arr"
-#endif
-
-mkDerivingCompatName_v :: String -> Name
-mkDerivingCompatName_v = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal"
-
-mkDerivingCompatName_tc :: String -> Name
-mkDerivingCompatName_tc = mkNameG_tc derivingCompatPackageKey "Data.Deriving.Internal"
+-- With GHC 8.0 or later, we can simply use TemplateHaskellQuotes to quote each
+-- name, which allows deriving-compat to be built with compilers that do not
+-- support Template Haskell (e.g., stage-1 cross compilers). Unfortunately,
+-- older versions of GHC must fall back on full-blown Template Haskell.
 
 isTrueHashValName :: Name
-isTrueHashValName = mkDerivingCompatName_v "isTrue#"
+isTrueHashValName = 'isTrue#
 
 fmapConstValName :: Name
-fmapConstValName = mkDerivingCompatName_v "fmapConst"
+fmapConstValName = 'fmapConst
 
 replaceConstValName :: Name
-replaceConstValName = mkDerivingCompatName_v "replaceConst"
+replaceConstValName = 'replaceConst
 
 foldrConstValName :: Name
-foldrConstValName = mkDerivingCompatName_v "foldrConst"
+foldrConstValName = 'foldrConst
 
 foldMapConstValName :: Name
-foldMapConstValName = mkDerivingCompatName_v "foldMapConst"
+foldMapConstValName = 'foldMapConst
 
 nullConstValName :: Name
-nullConstValName = mkDerivingCompatName_v "nullConst"
+nullConstValName = 'nullConst
 
 traverseConstValName :: Name
-traverseConstValName = mkDerivingCompatName_v "traverseConst"
+traverseConstValName = 'traverseConst
 
 eqConstValName :: Name
-eqConstValName = mkDerivingCompatName_v "eqConst"
+eqConstValName = 'eqConst
 
 eq1ConstValName :: Name
-eq1ConstValName = mkDerivingCompatName_v "eq1Const"
+eq1ConstValName = 'eq1Const
 
 liftEqConstValName :: Name
-liftEqConstValName = mkDerivingCompatName_v "liftEqConst"
+liftEqConstValName = 'liftEqConst
 
 liftEq2ConstValName :: Name
-liftEq2ConstValName = mkDerivingCompatName_v "liftEq2Const"
+liftEq2ConstValName = 'liftEq2Const
 
 compareConstValName :: Name
-compareConstValName = mkDerivingCompatName_v "compareConst"
+compareConstValName = 'compareConst
 
 ltConstValName :: Name
-ltConstValName = mkDerivingCompatName_v "ltConst"
+ltConstValName = 'ltConst
 
 compare1ConstValName :: Name
-compare1ConstValName = mkDerivingCompatName_v "compare1Const"
+compare1ConstValName = 'compare1Const
 
 liftCompareConstValName :: Name
-liftCompareConstValName = mkDerivingCompatName_v "liftCompareConst"
+liftCompareConstValName = 'liftCompareConst
 
 liftCompare2ConstValName :: Name
-liftCompare2ConstValName = mkDerivingCompatName_v "liftCompare2Const"
+liftCompare2ConstValName = 'liftCompare2Const
 
 readsPrecConstValName :: Name
-readsPrecConstValName = mkDerivingCompatName_v "readsPrecConst"
+readsPrecConstValName = 'readsPrecConst
 
 readPrecConstValName :: Name
-readPrecConstValName = mkDerivingCompatName_v "readPrecConst"
+readPrecConstValName = 'readPrecConst
 
 readsPrec1ConstValName :: Name
-readsPrec1ConstValName = mkDerivingCompatName_v "readsPrec1Const"
+readsPrec1ConstValName = 'readsPrec1Const
 
 liftReadsPrecConstValName :: Name
-liftReadsPrecConstValName = mkDerivingCompatName_v "liftReadsPrecConst"
+liftReadsPrecConstValName = 'liftReadsPrecConst
 
 liftReadPrecConstValName :: Name
-liftReadPrecConstValName = mkDerivingCompatName_v "liftReadPrecConst"
+liftReadPrecConstValName = 'liftReadPrecConst
 
 liftReadsPrec2ConstValName :: Name
-liftReadsPrec2ConstValName = mkDerivingCompatName_v "liftReadsPrec2Const"
+liftReadsPrec2ConstValName = 'liftReadsPrec2Const
 
 liftReadPrec2ConstValName :: Name
-liftReadPrec2ConstValName = mkDerivingCompatName_v "liftReadPrec2Const"
+liftReadPrec2ConstValName = 'liftReadPrec2Const
 
 showsPrecConstValName :: Name
-showsPrecConstValName = mkDerivingCompatName_v "showsPrecConst"
+showsPrecConstValName = 'showsPrecConst
 
 showsPrec1ConstValName :: Name
-showsPrec1ConstValName = mkDerivingCompatName_v "showsPrec1Const"
+showsPrec1ConstValName = 'showsPrec1Const
 
 liftShowsPrecConstValName :: Name
-liftShowsPrecConstValName = mkDerivingCompatName_v "liftShowsPrecConst"
+liftShowsPrecConstValName = 'liftShowsPrecConst
 
 liftShowsPrec2ConstValName :: Name
-liftShowsPrec2ConstValName = mkDerivingCompatName_v "liftShowsPrec2Const"
+liftShowsPrec2ConstValName = 'liftShowsPrec2Const
 
 viaTypeName :: Name
-viaTypeName = mkDerivingCompatName_tc "Via"
+viaTypeName = ''Via
 
 cHashDataName :: Name
-cHashDataName = mkNameG_d "ghc-prim" "GHC.Types" "C#"
+cHashDataName = 'C#
 
 dHashDataName :: Name
-dHashDataName = mkNameG_d "ghc-prim" "GHC.Types" "D#"
+dHashDataName = 'D#
 
 fHashDataName :: Name
-fHashDataName = mkNameG_d "ghc-prim" "GHC.Types" "F#"
+fHashDataName = 'F#
 
 identDataName :: Name
-identDataName = mkNameG_d "base" "Text.Read.Lex" "Ident"
+identDataName = 'L.Ident
 
 iHashDataName :: Name
-iHashDataName = mkNameG_d "ghc-prim" "GHC.Types" "I#"
+iHashDataName = 'I#
 
 puncDataName :: Name
-puncDataName = mkNameG_d "base" "Text.Read.Lex" "Punc"
+puncDataName = 'L.Punc
 
 symbolDataName :: Name
-symbolDataName = mkNameG_d "base" "Text.Read.Lex" "Symbol"
+symbolDataName = 'L.Symbol
 
 wrapMonadDataName :: Name
-wrapMonadDataName = mkNameG_d "base" "Control.Applicative" "WrapMonad"
+wrapMonadDataName = 'App.WrapMonad
 
 addrHashTypeName :: Name
-addrHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Addr#"
+addrHashTypeName = ''Addr#
 
 boundedTypeName :: Name
-boundedTypeName = mkNameG_tc "base" "GHC.Enum" "Bounded"
+boundedTypeName = ''Bounded
 
 charHashTypeName :: Name
-charHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Char#"
+charHashTypeName = ''Char#
 
 doubleHashTypeName :: Name
-doubleHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Double#"
+doubleHashTypeName = ''Double#
 
 enumTypeName :: Name
-enumTypeName = mkNameG_tc "base" "GHC.Enum" "Enum"
+enumTypeName = ''Enum
 
 floatHashTypeName :: Name
-floatHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Float#"
+floatHashTypeName = ''Float#
 
 foldableTypeName :: Name
-foldableTypeName = mkNameG_tc "base" "Data.Foldable" "Foldable"
+foldableTypeName = ''Foldable
 
 functorTypeName :: Name
-functorTypeName = mkNameG_tc "base" "GHC.Base" "Functor"
+functorTypeName = ''Functor
 
 intTypeName :: Name
-intTypeName = mkNameG_tc "ghc-prim" "GHC.Types" "Int"
+intTypeName = ''Int
 
 intHashTypeName :: Name
-intHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Int#"
+intHashTypeName = ''Int#
 
 ixTypeName :: Name
-ixTypeName = mkNameG_tc "base" gHC_IX "Ix"
+ixTypeName = ''Ix
 
 readTypeName :: Name
-readTypeName = mkNameG_tc "base" "GHC.Read" "Read"
+readTypeName = ''Read
 
 showTypeName :: Name
-showTypeName = mkNameG_tc "base" "GHC.Show" "Show"
+showTypeName = ''Show
 
 traversableTypeName :: Name
-traversableTypeName = mkNameG_tc "base" "Data.Traversable" "Traversable"
+traversableTypeName = ''Traversable
 
 wordHashTypeName :: Name
-wordHashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Word#"
+wordHashTypeName = ''Word#
 
 altValName :: Name
-altValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "+++"
+altValName = '(+++)
 
 appendValName :: Name
-appendValName = mkNameG_v "base" "GHC.Base" "++"
+appendValName = '(++)
 
 chooseValName :: Name
-chooseValName = mkNameG_v "base" "GHC.Read" "choose"
-
-coerceValName :: Name
-coerceValName = mkNameG_v "ghc-prim" "GHC.Prim" "coerce"
+chooseValName = 'choose
 
 composeValName :: Name
-composeValName = mkNameG_v "base" "GHC.Base" "."
+composeValName = '(.)
 
 constValName :: Name
-constValName = mkNameG_v "base" "GHC.Base" "const"
+constValName = 'const
 
 enumFromValName :: Name
-enumFromValName = mkNameG_v "base" "GHC.Enum" "enumFrom"
+enumFromValName = 'enumFrom
 
 enumFromThenValName :: Name
-enumFromThenValName = mkNameG_v "base" "GHC.Enum" "enumFromThen"
+enumFromThenValName = 'enumFromThen
 
 enumFromThenToValName :: Name
-enumFromThenToValName = mkNameG_v "base" "GHC.Enum" "enumFromThenTo"
+enumFromThenToValName = 'enumFromThenTo
 
 enumFromToValName :: Name
-enumFromToValName = mkNameG_v "base" "GHC.Enum" "enumFromTo"
+enumFromToValName = 'enumFromTo
 
 eqAddrHashValName :: Name
-eqAddrHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqAddr#"
+eqAddrHashValName = 'eqAddr#
 
 eqCharHashValName :: Name
-eqCharHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqChar#"
+eqCharHashValName = 'eqChar#
 
 eqDoubleHashValName :: Name
-eqDoubleHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "==##"
+eqDoubleHashValName = '(==##)
 
 eqFloatHashValName :: Name
-eqFloatHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqFloat#"
+eqFloatHashValName = 'eqFloat#
 
 eqIntHashValName :: Name
-eqIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "==#"
+eqIntHashValName = '(==#)
 
 eqWordHashValName :: Name
-eqWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqWord#"
+eqWordHashValName = 'eqWord#
 
 errorValName :: Name
-errorValName = mkNameG_v "base" "GHC.Err" "error"
+errorValName = 'error
 
 flipValName :: Name
-flipValName = mkNameG_v "base" "GHC.Base" "flip"
+flipValName = 'flip
 
 fmapValName :: Name
-fmapValName = mkNameG_v "base" "GHC.Base" "fmap"
+fmapValName = 'fmap
 
 foldrValName :: Name
-foldrValName = mkNameG_v "base" "Data.Foldable" "foldr"
+foldrValName = 'F.foldr
 
 foldMapValName :: Name
-foldMapValName = mkNameG_v "base" "Data.Foldable" "foldMap"
+foldMapValName = 'foldMap
 
 fromEnumValName :: Name
-fromEnumValName = mkNameG_v "base" "GHC.Enum" "fromEnum"
+fromEnumValName = 'fromEnum
 
 geAddrHashValName :: Name
-geAddrHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geAddr#"
+geAddrHashValName = 'geAddr#
 
 geCharHashValName :: Name
-geCharHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geChar#"
+geCharHashValName = 'geChar#
 
 geDoubleHashValName :: Name
-geDoubleHashValName = mkNameG_v "ghc-prim" "GHC.Prim" ">=##"
+geDoubleHashValName = '(>=##)
 
 geFloatHashValName :: Name
-geFloatHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geFloat#"
+geFloatHashValName = 'geFloat#
 
 geIntHashValName :: Name
-geIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" ">=#"
+geIntHashValName = '(>=#)
 
 getTagValName :: Name
-getTagValName = mkNameG_v "base" "GHC.Base" "getTag"
+getTagValName = 'getTag
 
 geWordHashValName :: Name
-geWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geWord#"
+geWordHashValName = 'geWord#
 
 gtAddrHashValName :: Name
-gtAddrHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtAddr#"
+gtAddrHashValName = 'gtAddr#
 
 gtCharHashValName :: Name
-gtCharHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtChar#"
+gtCharHashValName = 'gtChar#
 
 gtDoubleHashValName :: Name
-gtDoubleHashValName = mkNameG_v "ghc-prim" "GHC.Prim" ">##"
+gtDoubleHashValName = '(>##)
 
 gtFloatHashValName :: Name
-gtFloatHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtFloat#"
+gtFloatHashValName = 'gtFloat#
 
 gtIntHashValName :: Name
-gtIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" ">#"
+gtIntHashValName = '(>#)
 
 gtWordHashValName :: Name
-gtWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtWord#"
+gtWordHashValName = 'gtWord#
 
 idValName :: Name
-idValName = mkNameG_v "base" "GHC.Base" "id"
+idValName = 'id
 
 indexValName :: Name
-indexValName = mkNameG_v "base" gHC_IX "index"
+indexValName = 'index
 
 inRangeValName :: Name
-inRangeValName = mkNameG_v "base" gHC_IX "inRange"
+inRangeValName = 'inRange
 
 leAddrHashValName :: Name
-leAddrHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leAddr#"
+leAddrHashValName = 'leAddr#
 
 leCharHashValName :: Name
-leCharHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leChar#"
+leCharHashValName = 'leChar#
 
 leDoubleHashValName :: Name
-leDoubleHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "<=##"
+leDoubleHashValName = '(<=##)
 
 leFloatHashValName :: Name
-leFloatHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leFloat#"
+leFloatHashValName = 'leFloat#
 
 leIntHashValName :: Name
-leIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "<=#"
+leIntHashValName = '(<=#)
 
 leWordHashValName :: Name
-leWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leWord#"
-
-liftReadListPrecDefaultValName :: Name
-liftReadListPrecDefaultValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadListPrecDefault"
-
-liftReadListPrec2DefaultValName :: Name
-liftReadListPrec2DefaultValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadListPrec2Default"
-
-liftReadListPrecValName :: Name
-liftReadListPrecValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadListPrec"
-
-liftReadListPrec2ValName :: Name
-liftReadListPrec2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadListPrec2"
-
-liftReadPrecValName :: Name
-liftReadPrecValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadPrec"
-
-liftReadPrec2ValName :: Name
-liftReadPrec2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadPrec2"
+leWordHashValName = 'leWord#
 
 listValName :: Name
-listValName = mkNameG_v "base" "GHC.Read" "list"
+listValName = 'list
 
 ltAddrHashValName :: Name
-ltAddrHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltAddr#"
+ltAddrHashValName = 'ltAddr#
 
 ltCharHashValName :: Name
-ltCharHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltChar#"
+ltCharHashValName = 'ltChar#
 
 ltDoubleHashValName :: Name
-ltDoubleHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "<##"
+ltDoubleHashValName = '(<##)
 
 ltFloatHashValName :: Name
-ltFloatHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltFloat#"
+ltFloatHashValName = 'ltFloat#
 
 ltIntHashValName :: Name
-ltIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "<#"
+ltIntHashValName = '(<#)
 
 ltWordHashValName :: Name
-ltWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltWord#"
+ltWordHashValName = 'ltWord#
 
 minBoundValName :: Name
-minBoundValName = mkNameG_v "base" "GHC.Enum" "minBound"
+minBoundValName = 'minBound
 
 mapValName :: Name
-mapValName = mkNameG_v "base" "GHC.Base" "map"
+mapValName = 'map
 
 maxBoundValName :: Name
-maxBoundValName = mkNameG_v "base" "GHC.Enum" "maxBound"
+maxBoundValName = 'maxBound
 
 minusIntHashValName :: Name
-minusIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "-#"
+minusIntHashValName = '(-#)
 
 neqIntHashValName :: Name
-neqIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "/=#"
+neqIntHashValName = '(/=#)
 
 parenValName :: Name
-parenValName = mkNameG_v "base" "GHC.Read" "paren"
+parenValName = 'paren
 
 parensValName :: Name
-parensValName = mkNameG_v "base" "GHC.Read" "parens"
+parensValName = 'parens
 
 pfailValName :: Name
-pfailValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "pfail"
+pfailValName = 'pfail
 
 plusValName :: Name
-plusValName = mkNameG_v "base" "GHC.Num" "+"
+plusValName = '(+)
 
 precValName :: Name
-precValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "prec"
+precValName = 'prec
 
 predValName :: Name
-predValName = mkNameG_v "base" "GHC.Enum" "pred"
+predValName = 'pred
 
 rangeSizeValName :: Name
-rangeSizeValName = mkNameG_v "base" gHC_IX "rangeSize"
+rangeSizeValName = 'rangeSize
 
 rangeValName :: Name
-rangeValName = mkNameG_v "base" gHC_IX "range"
+rangeValName = 'range
 
 readFieldHash :: String -> ReadPrec a -> ReadPrec a
 readFieldHash fieldName readVal = do
@@ -1608,323 +1588,195 @@
 {-# NOINLINE readFieldHash #-}
 
 readFieldHashValName :: Name
-readFieldHashValName = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal" "readFieldHash"
+readFieldHashValName = 'readFieldHash
 
 readListValName :: Name
-readListValName = mkNameG_v "base" "GHC.Read" "readList"
+readListValName = 'readList
 
 readListPrecDefaultValName :: Name
-readListPrecDefaultValName = mkNameG_v "base" "GHC.Read" "readListPrecDefault"
+readListPrecDefaultValName = 'readListPrecDefault
 
 readListPrecValName :: Name
-readListPrecValName = mkNameG_v "base" "GHC.Read" "readListPrec"
+readListPrecValName = 'readListPrec
 
 readPrec_to_SValName :: Name
-readPrec_to_SValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "readPrec_to_S"
+readPrec_to_SValName = 'readPrec_to_S
 
 readPrecValName :: Name
-readPrecValName = mkNameG_v "base" "GHC.Read" "readPrec"
+readPrecValName = 'readPrec
 
 readS_to_PrecValName :: Name
-readS_to_PrecValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "readS_to_Prec"
+readS_to_PrecValName = 'readS_to_Prec
 
 readsPrecValName :: Name
-readsPrecValName = mkNameG_v "base" "GHC.Read" "readsPrec"
+readsPrecValName = 'readsPrec
 
 replaceValName :: Name
-replaceValName = mkNameG_v "base" "GHC.Base" "<$"
+replaceValName = '(<$)
 
 resetValName :: Name
-resetValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "reset"
+resetValName = 'reset
 
 returnValName :: Name
-returnValName = mkNameG_v "base" "GHC.Base" "return"
+returnValName = 'return
 
 seqValName :: Name
-seqValName = mkNameG_v "ghc-prim" "GHC.Prim" "seq"
+seqValName = 'seq
 
 showCharValName :: Name
-showCharValName = mkNameG_v "base" "GHC.Show" "showChar"
+showCharValName = 'showChar
 
 showListValName :: Name
-showListValName = mkNameG_v "base" "GHC.Show" "showList"
+showListValName = 'showList
 
 showListWithValName :: Name
-showListWithValName = mkNameG_v "base" "Text.Show" "showListWith"
+showListWithValName = 'showListWith
 
 showParenValName :: Name
-showParenValName = mkNameG_v "base" "GHC.Show" "showParen"
+showParenValName = 'showParen
 
 showsPrecValName :: Name
-showsPrecValName = mkNameG_v "base" "GHC.Show" "showsPrec"
+showsPrecValName = 'showsPrec
 
 showSpaceValName :: Name
-showSpaceValName = mkNameG_v "base" "GHC.Show" "showSpace"
+showSpaceValName = 'showSpace
 
 showStringValName :: Name
-showStringValName = mkNameG_v "base" "GHC.Show" "showString"
+showStringValName = 'showString
 
 stepValName :: Name
-stepValName = mkNameG_v "base" "Text.ParserCombinators.ReadPrec" "step"
+stepValName = 'step
 
 succValName :: Name
-succValName = mkNameG_v "base" "GHC.Enum" "succ"
+succValName = 'succ
 
 tagToEnumHashValName :: Name
-tagToEnumHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "tagToEnum#"
+tagToEnumHashValName = 'tagToEnum#
 
 timesValName :: Name
-timesValName = mkNameG_v "base" "GHC.Num" "*"
+timesValName = '(*)
 
 toEnumValName :: Name
-toEnumValName = mkNameG_v "base" "GHC.Enum" "toEnum"
+toEnumValName = 'toEnum
 
 traverseValName :: Name
-traverseValName = mkNameG_v "base" "Data.Traversable" "traverse"
+traverseValName = 'traverse
 
 unsafeIndexValName :: Name
-unsafeIndexValName = mkNameG_v "base" gHC_IX "unsafeIndex"
+unsafeIndexValName = 'unsafeIndex
 
 unsafeRangeSizeValName :: Name
-unsafeRangeSizeValName = mkNameG_v "base" gHC_IX "unsafeRangeSize"
+unsafeRangeSizeValName = 'unsafeRangeSize
 
 unwrapMonadValName :: Name
-unwrapMonadValName = mkNameG_v "base" "Control.Applicative" "unwrapMonad"
+unwrapMonadValName = 'App.unwrapMonad
 
-#if MIN_VERSION_base(4,4,0)
 boolTypeName :: Name
-boolTypeName = mkNameG_tc "ghc-prim" "GHC.Types" "Bool"
-
-falseDataName :: Name
-falseDataName = mkNameG_d "ghc-prim" "GHC.Types" "False"
-
-trueDataName :: Name
-trueDataName = mkNameG_d "ghc-prim" "GHC.Types" "True"
-#else
-boolTypeName :: Name
-boolTypeName = mkNameG_tc "ghc-prim" "GHC.Bool" "Bool"
+boolTypeName = ''Bool
 
 falseDataName :: Name
-falseDataName = mkNameG_d "ghc-prim" "GHC.Bool" "False"
+falseDataName = 'False
 
 trueDataName :: Name
-trueDataName = mkNameG_d "ghc-prim" "GHC.Bool" "True"
-#endif
+trueDataName = 'True
 
-#if MIN_VERSION_base(4,5,0)
 eqDataName :: Name
-eqDataName = mkNameG_d "ghc-prim" "GHC.Types" "EQ"
-
-gtDataName :: Name
-gtDataName = mkNameG_d "ghc-prim" "GHC.Types" "GT"
-
-ltDataName :: Name
-ltDataName = mkNameG_d "ghc-prim" "GHC.Types" "LT"
-
-eqTypeName :: Name
-eqTypeName = mkNameG_tc "ghc-prim" "GHC.Classes" "Eq"
-
-ordTypeName :: Name
-ordTypeName = mkNameG_tc "ghc-prim" "GHC.Classes" "Ord"
-
-andValName :: Name
-andValName = mkNameG_v "ghc-prim" "GHC.Classes" "&&"
-
-compareValName :: Name
-compareValName = mkNameG_v "ghc-prim" "GHC.Classes" "compare"
-
-eqValName :: Name
-eqValName = mkNameG_v "ghc-prim" "GHC.Classes" "=="
-
-geValName :: Name
-geValName = mkNameG_v "ghc-prim" "GHC.Classes" ">="
-
-gtValName :: Name
-gtValName = mkNameG_v "ghc-prim" "GHC.Classes" ">"
-
-leValName :: Name
-leValName = mkNameG_v "ghc-prim" "GHC.Classes" "<="
-
-ltValName :: Name
-ltValName = mkNameG_v "ghc-prim" "GHC.Classes" "<"
-
-notValName :: Name
-notValName = mkNameG_v "ghc-prim" "GHC.Classes" "not"
-#else
-eqDataName :: Name
-eqDataName = mkNameG_d "ghc-prim" "GHC.Ordering" "EQ"
+eqDataName = 'EQ
 
 gtDataName :: Name
-gtDataName = mkNameG_d "ghc-prim" "GHC.Ordering" "GT"
+gtDataName = 'GT
 
 ltDataName :: Name
-ltDataName = mkNameG_d "ghc-prim" "GHC.Ordering" "LT"
+ltDataName = 'LT
 
 eqTypeName :: Name
-eqTypeName = mkNameG_tc "base" "GHC.Classes" "Eq"
+eqTypeName = ''Eq
 
 ordTypeName :: Name
-ordTypeName = mkNameG_tc "base" "GHC.Classes" "Ord"
+ordTypeName = ''Ord
 
 andValName :: Name
-andValName = mkNameG_v "base" "GHC.Classes" "&&"
+andValName = '(&&)
 
 compareValName :: Name
-compareValName = mkNameG_v "base" "GHC.Classes" "compare"
+compareValName = 'compare
 
 eqValName :: Name
-eqValName = mkNameG_v "base" "GHC.Classes" "=="
+eqValName = '(==)
 
 geValName :: Name
-geValName = mkNameG_v "base" "GHC.Classes" ">="
+geValName = '(>=)
 
 gtValName :: Name
-gtValName = mkNameG_v "base" "GHC.Classes" ">"
+gtValName = '(>)
 
 leValName :: Name
-leValName = mkNameG_v "base" "GHC.Classes" "<="
+leValName = '(<=)
 
 ltValName :: Name
-ltValName = mkNameG_v "base" "GHC.Classes" "<"
+ltValName = '(<)
 
 notValName :: Name
-notValName = mkNameG_v "base" "GHC.Classes" "not"
-#endif
+notValName = 'not
 
-#if MIN_VERSION_base(4,6,0)
 wHashDataName :: Name
-wHashDataName = mkNameG_d "ghc-prim" "GHC.Types" "W#"
-#else
-wHashDataName :: Name
-wHashDataName = mkNameG_d "base" "GHC.Word" "W#"
-#endif
+wHashDataName = 'W#
 
-#if MIN_VERSION_base(4,7,0)
-expectPValName :: Name
-expectPValName = mkNameG_v "base" "GHC.Read" "expectP"
-#else
+#if !(MIN_VERSION_base(4,7,0))
 expectP :: Lexeme -> ReadPrec ()
 expectP lexeme = do
   thing <- lexP
   if thing == lexeme then return () else pfail
+#endif
 
 expectPValName :: Name
-expectPValName = mkDerivingCompatName_v "expectP"
-#endif
+expectPValName = 'expectP
 
-#if MIN_VERSION_base(4,8,0)
 allValName :: Name
-allValName = mkNameG_v "base" "Data.Foldable" "all"
-
-apValName :: Name
-apValName = mkNameG_v "base" "GHC.Base" "<*>"
-
-pureValName :: Name
-pureValName = mkNameG_v "base" "GHC.Base" "pure"
-
-liftA2ValName :: Name
-liftA2ValName = mkNameG_v "base" "GHC.Base" "liftA2"
-
-mappendValName :: Name
-mappendValName = mkNameG_v "base" "GHC.Base" "mappend"
-
-memptyValName :: Name
-memptyValName = mkNameG_v "base" "GHC.Base" "mempty"
-
-nullValName :: Name
-nullValName = mkNameG_v "base" "Data.Foldable" "null"
-#else
-allValName :: Name
-allValName = mkNameG_v "base" "GHC.List" "all"
+allValName = 'all
 
 apValName :: Name
-apValName = mkNameG_v "base" "Control.Applicative" "<*>"
+apValName = '(<*>)
 
 pureValName :: Name
-pureValName = mkNameG_v "base" "Control.Applicative" "pure"
+pureValName = 'pure
 
 liftA2ValName :: Name
-liftA2ValName = mkNameG_v "base" "Control.Applicative" "liftA2"
+liftA2ValName = 'App.liftA2
 
 mappendValName :: Name
-mappendValName = mkNameG_v "base" "Data.Monoid" "mappend"
+mappendValName = 'mappend
 
 memptyValName :: Name
-memptyValName = mkNameG_v "base" "Data.Monoid" "mempty"
+memptyValName = 'mempty
 
 nullValName :: Name
-nullValName = mkNameG_v "base" "GHC.List" "null"
-#endif
+nullValName = 'null
 
-#if MIN_VERSION_base(4,9,0)
 eq1TypeName :: Name
-eq1TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Eq1"
-
-eq2TypeName :: Name
-eq2TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Eq2"
-
-liftEqValName :: Name
-liftEqValName = mkNameG_v "base" "Data.Functor.Classes" "liftEq"
-
-liftEq2ValName :: Name
-liftEq2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftEq2"
+eq1TypeName = ''Eq1
 
 ord1TypeName :: Name
-ord1TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Ord1"
-
-ord2TypeName :: Name
-ord2TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Ord2"
-
-liftCompareValName :: Name
-liftCompareValName = mkNameG_v "base" "Data.Functor.Classes" "liftCompare"
-
-liftCompare2ValName :: Name
-liftCompare2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftCompare2"
+ord1TypeName = ''Ord1
 
 read1TypeName :: Name
-read1TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Read1"
-
-read2TypeName :: Name
-read2TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Read2"
-
-liftReadsPrecValName :: Name
-liftReadsPrecValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadsPrec"
-
-liftReadListValName :: Name
-liftReadListValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadList"
-
-liftReadsPrec2ValName :: Name
-liftReadsPrec2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadsPrec2"
-
-liftReadList2ValName :: Name
-liftReadList2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftReadList2"
+read1TypeName = ''Read1
 
 show1TypeName :: Name
-show1TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Show1"
-
-show2TypeName :: Name
-show2TypeName = mkNameG_tc "base" "Data.Functor.Classes" "Show2"
-
-liftShowListValName :: Name
-liftShowListValName = mkNameG_v "base" "Data.Functor.Classes" "liftShowList"
+show1TypeName = ''Show1
 
-liftShowsPrecValName :: Name
-liftShowsPrecValName = mkNameG_v "base" "Data.Functor.Classes" "liftShowsPrec"
+#if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
+eq2TypeName :: Name
+eq2TypeName = ''Eq2
 
-liftShowList2ValName :: Name
-liftShowList2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftShowList2"
+ord2TypeName :: Name
+ord2TypeName = ''Ord2
 
-liftShowsPrec2ValName :: Name
-liftShowsPrec2ValName = mkNameG_v "base" "Data.Functor.Classes" "liftShowsPrec2"
-#else
--- If Data.Functor.Classes isn't located in base, then sadly we can't refer to
--- Names from that module without using -XTemplateHaskell.
-# if !(MIN_VERSION_transformers(0,4,0)) || MIN_VERSION_transformers(0,5,0)
-eq1TypeName :: Name
-eq1TypeName = ''Eq1
+read2TypeName :: Name
+read2TypeName = ''Read2
 
-eq2TypeName :: Name
-eq2TypeName = ''Eq2
+show2TypeName :: Name
+show2TypeName = ''Show2
 
 liftEqValName :: Name
 liftEqValName = 'liftEq
@@ -1932,24 +1784,12 @@
 liftEq2ValName :: Name
 liftEq2ValName = 'liftEq2
 
-ord1TypeName :: Name
-ord1TypeName = ''Ord1
-
-ord2TypeName :: Name
-ord2TypeName = ''Ord2
-
 liftCompareValName :: Name
 liftCompareValName = 'liftCompare
 
 liftCompare2ValName :: Name
 liftCompare2ValName = 'liftCompare2
 
-read1TypeName :: Name
-read1TypeName = ''Read1
-
-read2TypeName :: Name
-read2TypeName = ''Read2
-
 liftReadsPrecValName :: Name
 liftReadsPrecValName = 'liftReadsPrec
 
@@ -1962,12 +1802,6 @@
 liftReadList2ValName :: Name
 liftReadList2ValName = 'liftReadList2
 
-show1TypeName :: Name
-show1TypeName = ''Show1
-
-show2TypeName :: Name
-show2TypeName = ''Show2
-
 liftShowListValName :: Name
 liftShowListValName = 'liftShowList
 
@@ -1979,28 +1813,16 @@
 
 liftShowsPrec2ValName :: Name
 liftShowsPrec2ValName = 'liftShowsPrec2
-# else
-eq1TypeName :: Name
-eq1TypeName = ''Eq1
-
+#else
 eq1ValName :: Name
 eq1ValName = 'eq1
 
-ord1TypeName :: Name
-ord1TypeName = ''Ord1
-
 compare1ValName :: Name
 compare1ValName = 'compare1
 
-read1TypeName :: Name
-read1TypeName = ''Read1
-
 readsPrec1ValName :: Name
 readsPrec1ValName = 'readsPrec1
 
-show1TypeName :: Name
-show1TypeName = ''Show1
-
 showsPrec1ValName :: Name
 showsPrec1ValName = 'showsPrec1
 
@@ -2053,55 +1875,85 @@
        else inspectTy (head rhsArgs)
 
 applyDataName :: Name
-applyDataName = mkNameG_d derivingCompatPackageKey "Data.Deriving.Internal" "Apply"
+applyDataName = 'Apply
 
 unApplyValName :: Name
-unApplyValName = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal" "unApply"
-# endif
+unApplyValName = 'unApply
 #endif
 
+#if MIN_VERSION_base(4,7,0)
+coerceValName :: Name
+coerceValName = 'coerce
+#endif
+
 #if MIN_VERSION_base(4,10,0)
-showCommaSpaceValName :: Name
-showCommaSpaceValName = mkNameG_v "base" "GHC.Show" "showCommaSpace"
+liftReadListPrecDefaultValName :: Name
+liftReadListPrecDefaultValName = 'liftReadListPrecDefault
+
+liftReadListPrec2DefaultValName :: Name
+liftReadListPrec2DefaultValName = 'liftReadListPrec2Default
+
+liftReadListPrecValName :: Name
+liftReadListPrecValName = 'liftReadListPrec
+
+liftReadListPrec2ValName :: Name
+liftReadListPrec2ValName = 'liftReadListPrec2
+
+liftReadPrecValName :: Name
+liftReadPrecValName = 'liftReadPrec
+
+liftReadPrec2ValName :: Name
+liftReadPrec2ValName = 'liftReadPrec2
 #else
-showCommaSpace :: ShowS
-showCommaSpace = showString ", "
+-- This is a gross hack to avoid needing to guard some uses of these two Names
+-- in Text.Read.Deriving.Internal with even grosser CPP.
 
-showCommaSpaceValName :: Name
-showCommaSpaceValName = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal" "showCommaSpace"
-#endif
+liftReadListPrecDefaultValName :: Name
+liftReadListPrecDefaultValName =
+  error "using liftReadListPrecDefault before base-4.10.*"
 
-#if MIN_VERSION_base(4,11,0)
-appEndoValName :: Name
-appEndoValName = mkNameG_v "base" "Data.Semigroup.Internal" "appEndo"
+liftReadListPrec2DefaultValName :: Name
+liftReadListPrec2DefaultValName =
+  error "using liftReadListPrec2Default before base-4.10.*"
 
-dualDataName :: Name
-dualDataName = mkNameG_d "base" "Data.Semigroup.Internal" "Dual"
+liftReadListPrecValName :: Name
+liftReadListPrecValName =
+  error "using liftReadListPrec before base-4.10.*"
 
-endoDataName :: Name
-endoDataName = mkNameG_d "base" "Data.Semigroup.Internal" "Endo"
+liftReadListPrec2ValName :: Name
+liftReadListPrec2ValName =
+  error "using liftReadListPrec2 before base-4.10.*"
 
-getDualValName :: Name
-getDualValName = mkNameG_v "base" "Data.Semigroup.Internal" "getDual"
+liftReadPrecValName :: Name
+liftReadPrecValName =
+  error "using liftReadPrec before base-4.10.*"
 
-readFieldValName :: Name
-readFieldValName = mkNameG_v "base" "GHC.Read" "readField"
+liftReadPrec2ValName :: Name
+liftReadPrec2ValName =
+  error "using liftReadPrec2 before base-4.10.*"
+#endif
 
-readSymFieldValName :: Name
-readSymFieldValName = mkNameG_v "base" "GHC.Read" "readSymField"
-#else
+#if !(MIN_VERSION_base(4,10,0))
+showCommaSpace :: ShowS
+showCommaSpace = showString ", "
+#endif
+
+showCommaSpaceValName :: Name
+showCommaSpaceValName = 'showCommaSpace
+
 appEndoValName :: Name
-appEndoValName = mkNameG_v "base" "Data.Monoid" "appEndo"
+appEndoValName = 'appEndo
 
 dualDataName :: Name
-dualDataName = mkNameG_d "base" "Data.Monoid" "Dual"
+dualDataName = 'Dual
 
 endoDataName :: Name
-endoDataName = mkNameG_d "base" "Data.Monoid" "Endo"
+endoDataName = 'Endo
 
 getDualValName :: Name
-getDualValName = mkNameG_v "base" "Data.Monoid" "getDual"
+getDualValName = 'getDual
 
+#if !(MIN_VERSION_base(4,11,0))
 readField :: String -> ReadPrec a -> ReadPrec a
 readField fieldName readVal = do
         expectP (L.Ident fieldName)
@@ -2109,9 +1961,6 @@
         readVal
 {-# NOINLINE readField #-}
 
-readFieldValName :: Name
-readFieldValName = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal" "readField"
-
 readSymField :: String -> ReadPrec a -> ReadPrec a
 readSymField fieldName readVal = do
         expectP (L.Punc "(")
@@ -2120,195 +1969,198 @@
         expectP (L.Punc "=")
         readVal
 {-# NOINLINE readSymField #-}
+#endif
 
+readFieldValName :: Name
+readFieldValName = 'readField
+
 readSymFieldValName :: Name
-readSymFieldValName = mkNameG_v derivingCompatPackageKey "Data.Deriving.Internal" "readSymField"
-#endif
+readSymFieldValName = 'readSymField
 
 #if MIN_VERSION_base(4,13,0)
 eqInt8HashValName :: Name
-eqInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqInt8#"
+eqInt8HashValName = 'eqInt8#
 
 eqInt16HashValName :: Name
-eqInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqInt16#"
+eqInt16HashValName = 'eqInt16#
 
 eqWord8HashValName :: Name
-eqWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqWord8#"
+eqWord8HashValName = 'eqWord8#
 
 eqWord16HashValName :: Name
-eqWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqWord16#"
+eqWord16HashValName = 'eqWord16#
 
 geInt8HashValName :: Name
-geInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geInt8#"
+geInt8HashValName = 'geInt8#
 
 geInt16HashValName :: Name
-geInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geInt16#"
+geInt16HashValName = 'geInt16#
 
 geWord8HashValName :: Name
-geWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geWord8#"
+geWord8HashValName = 'geWord8#
 
 geWord16HashValName :: Name
-geWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geWord16#"
+geWord16HashValName = 'geWord16#
 
 gtInt8HashValName :: Name
-gtInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtInt8#"
+gtInt8HashValName = 'gtInt8#
 
 gtInt16HashValName :: Name
-gtInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtInt16#"
+gtInt16HashValName = 'gtInt16#
 
 gtWord8HashValName :: Name
-gtWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtWord8#"
+gtWord8HashValName = 'gtWord8#
 
 gtWord16HashValName :: Name
-gtWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtWord16#"
+gtWord16HashValName = 'gtWord16#
 
 int8HashTypeName :: Name
-int8HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Int8#"
+int8HashTypeName = ''Int8#
 
 int8ToIntHashValName :: Name
-int8ToIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+int8ToIntHashValName =
 # if MIN_VERSION_base(4,16,0)
-  "int8ToInt#"
+  'int8ToInt#
 # else
-  "extendInt8#"
+  'extendInt8#
 # endif
 
 int16HashTypeName :: Name
-int16HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Int16#"
+int16HashTypeName = ''Int16#
 
 int16ToIntHashValName :: Name
-int16ToIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+int16ToIntHashValName =
 # if MIN_VERSION_base(4,16,0)
-  "int16ToInt#"
+  'int16ToInt#
 # else
-  "extendInt16#"
+  'extendInt16#
 # endif
 
 intToInt8HashValName :: Name
-intToInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+intToInt8HashValName =
 # if MIN_VERSION_base(4,16,0)
-  "intToInt8#"
+  'intToInt8#
 # else
-  "narrowInt8#"
+  'narrowInt8#
 # endif
 
 intToInt16HashValName :: Name
-intToInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+intToInt16HashValName =
 # if MIN_VERSION_base(4,16,0)
-  "intToInt16#"
+  'intToInt16#
 # else
-  "narrowInt16#"
+  'narrowInt16#
 # endif
 
 leInt8HashValName :: Name
-leInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leInt8#"
+leInt8HashValName = 'leInt8#
 
 leInt16HashValName :: Name
-leInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leInt16#"
+leInt16HashValName = 'leInt16#
 
 leWord8HashValName :: Name
-leWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leWord8#"
+leWord8HashValName = 'leWord8#
 
 leWord16HashValName :: Name
-leWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leWord16#"
+leWord16HashValName = 'leWord16#
 
 ltInt8HashValName :: Name
-ltInt8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltInt8#"
+ltInt8HashValName = 'ltInt8#
 
 ltInt16HashValName :: Name
-ltInt16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltInt16#"
+ltInt16HashValName = 'ltInt16#
 
 ltWord8HashValName :: Name
-ltWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltWord8#"
+ltWord8HashValName = 'ltWord8#
 
 ltWord16HashValName :: Name
-ltWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltWord16#"
+ltWord16HashValName = 'ltWord16#
 
 word8HashTypeName :: Name
-word8HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Word8#"
+word8HashTypeName = ''Word8#
 
 word8ToWordHashValName :: Name
-word8ToWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+word8ToWordHashValName =
 # if MIN_VERSION_base(4,16,0)
-  "word8ToWord#"
+  'word8ToWord#
 # else
-  "extendWord8#"
+  'extendWord8#
 # endif
 
 word16HashTypeName :: Name
-word16HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Word16#"
+word16HashTypeName = ''Word16#
 
 word16ToWordHashValName :: Name
-word16ToWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+word16ToWordHashValName =
 # if MIN_VERSION_base(4,16,0)
-  "word16ToWord#"
+  'word16ToWord#
 # else
-  "extendWord16#"
+  'extendWord16#
 # endif
 
 wordToWord8HashValName :: Name
-wordToWord8HashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+wordToWord8HashValName =
 # if MIN_VERSION_base(4,16,0)
-  "wordToWord8#"
+  'wordToWord8#
 # else
-  "narrowWord8#"
+  'narrowWord8#
 # endif
 
 wordToWord16HashValName :: Name
-wordToWord16HashValName = mkNameG_v "ghc-prim" "GHC.Prim"
+wordToWord16HashValName =
 # if MIN_VERSION_base(4,16,0)
-  "wordToWord16#"
+  'wordToWord16#
 # else
-  "narrowWord16#"
+  'narrowWord16#
 # endif
 #endif
 
 #if MIN_VERSION_base(4,16,0)
 eqInt32HashValName :: Name
-eqInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqInt32#"
+eqInt32HashValName = 'eqInt32#
 
 eqWord32HashValName :: Name
-eqWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "eqWord32#"
+eqWord32HashValName = 'eqWord32#
 
 geInt32HashValName :: Name
-geInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geInt32#"
+geInt32HashValName = 'geInt32#
 
 geWord32HashValName :: Name
-geWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "geWord32#"
+geWord32HashValName = 'geWord32#
 
 gtInt32HashValName :: Name
-gtInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtInt32#"
+gtInt32HashValName = 'gtInt32#
 
 gtWord32HashValName :: Name
-gtWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "gtWord32#"
+gtWord32HashValName = 'gtWord32#
 
 int32HashTypeName :: Name
-int32HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Int32#"
+int32HashTypeName = ''Int32#
 
 int32ToIntHashValName :: Name
-int32ToIntHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "int32ToInt#"
+int32ToIntHashValName = 'int32ToInt#
 
 intToInt32HashValName :: Name
-intToInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "intToInt32#"
+intToInt32HashValName = 'intToInt32#
 
 leInt32HashValName :: Name
-leInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leInt32#"
+leInt32HashValName = 'leInt32#
 
 leWord32HashValName :: Name
-leWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "leWord32#"
+leWord32HashValName = 'leWord32#
 
 ltInt32HashValName :: Name
-ltInt32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltInt32#"
+ltInt32HashValName = 'ltInt32#
 
 ltWord32HashValName :: Name
-ltWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "ltWord32#"
+ltWord32HashValName = 'ltWord32#
 
 word32HashTypeName :: Name
-word32HashTypeName = mkNameG_tc "ghc-prim" "GHC.Prim" "Word32#"
+word32HashTypeName = ''Word32#
 
 word32ToWordHashValName :: Name
-word32ToWordHashValName = mkNameG_v "ghc-prim" "GHC.Prim" "word32ToWord#"
+word32ToWordHashValName = 'word32ToWord#
 
 wordToWord32HashValName :: Name
-wordToWord32HashValName = mkNameG_v "ghc-prim" "GHC.Prim" "wordToWord32#"
+wordToWord32HashValName = 'wordToWord32#
 #endif
diff --git a/src/Data/Deriving/Via/Internal.hs b/src/Data/Deriving/Via/Internal.hs
--- a/src/Data/Deriving/Via/Internal.hs
+++ b/src/Data/Deriving/Via/Internal.hs
@@ -148,7 +148,7 @@
         _ -> fail $ "Not a type class: " ++ pprint clsTy
     _ -> fail $ "Malformed instance: " ++ pprint instanceTy
 
-deriveViaDecs' :: Name -> [TyVarBndrUnit] -> [Type] -> Type -> Dec -> Q (Maybe [Dec])
+deriveViaDecs' :: Name -> [TyVarBndr_ flag] -> [Type] -> Type -> Dec -> Q (Maybe [Dec])
 deriveViaDecs' clsName clsTvbs clsArgs repTy dec = do
     let numExpectedArgs = length clsTvbs
         numActualArgs   = length clsArgs
@@ -187,7 +187,7 @@
 
     go _ = return Nothing
 
-mkCoerceClassMethEqn :: [TyVarBndrUnit] -> [Type] -> Type -> Type -> (Type, Type)
+mkCoerceClassMethEqn :: [TyVarBndr_ flag] -> [Type] -> Type -> Type -> (Type, Type)
 mkCoerceClassMethEqn clsTvbs clsArgs repTy methTy
   = ( applySubstitution rhsSubst methTy
     , applySubstitution lhsSubst methTy
diff --git a/src/Data/Enum/Deriving/Internal.hs b/src/Data/Enum/Deriving/Internal.hs
--- a/src/Data/Enum/Deriving/Internal.hs
+++ b/src/Data/Enum/Deriving/Internal.hs
@@ -22,6 +22,7 @@
     ) where
 
 import Data.Deriving.Internal
+import Data.List.NonEmpty (NonEmpty(..))
 
 import Language.Haskell.TH.Datatype
 import Language.Haskell.TH.Lib
@@ -116,7 +117,7 @@
 -- given constructors. All constructors must be from the same type.
 makeEnumFunForCons :: EnumFun -> Name -> Type -> [ConstructorInfo] -> Q Exp
 makeEnumFunForCons _  _      _  [] = noConstructorsError
-makeEnumFunForCons ef tyName ty cons
+makeEnumFunForCons ef tyName ty (con:cons')
     | not $ isEnumerationType cons
     = enumerationError tyNameBase
     | otherwise = case ef of
@@ -173,8 +174,11 @@
     tyNameBase :: String
     tyNameBase = nameBase tyName
 
+    cons :: NonEmpty ConstructorInfo
+    cons = con :| cons'
+
     maxTagExpr :: Q Exp
-    maxTagExpr = integerE (length cons - 1) `sigE` conT intTypeName
+    maxTagExpr = integerE (length cons') `sigE` conT intTypeName
 
     lamOne :: (Name -> Q Exp) -> Q Exp
     lamOne f = do
diff --git a/src/Data/Ix/Deriving/Internal.hs b/src/Data/Ix/Deriving/Internal.hs
--- a/src/Data/Ix/Deriving/Internal.hs
+++ b/src/Data/Ix/Deriving/Internal.hs
@@ -19,6 +19,7 @@
     ) where
 
 import Data.Deriving.Internal
+import Data.List.NonEmpty (NonEmpty(..))
 
 import Language.Haskell.TH.Datatype
 import Language.Haskell.TH.Lib
@@ -95,7 +96,7 @@
 -- given constructors. All constructors must be from the same type.
 makeIxFunForCons :: IxFun -> Name -> Type -> [ConstructorInfo] -> Q Exp
 makeIxFunForCons _   _      _  [] = noConstructorsError
-makeIxFunForCons ixf tyName ty cons
+makeIxFunForCons ixf tyName ty (con:cons')
     | not (isProduct || isEnumeration)
     = enumerationOrProductError $ nameBase tyName
     | isEnumeration
@@ -144,10 +145,7 @@
                     ]
 
     | otherwise -- It's a product type
-    = do let con :: ConstructorInfo
-             con = head cons
-
-             conName :: Name
+    = do let conName :: Name
              conName = constructorName con
 
              conFields :: Int
@@ -204,6 +202,9 @@
                mkInRange a b c = varE inRangeValName `appE` tupE [varE a, varE b]
                                                      `appE` varE c
   where
+    cons :: NonEmpty ConstructorInfo
+    cons = con :| cons'
+
     isProduct, isEnumeration :: Bool
     isProduct     = isProductType cons
     isEnumeration = isEnumerationType cons
diff --git a/src/Data/Ord/Deriving/Internal.hs b/src/Data/Ord/Deriving/Internal.hs
--- a/src/Data/Ord/Deriving/Internal.hs
+++ b/src/Data/Ord/Deriving/Internal.hs
@@ -39,6 +39,8 @@
 
 import           Data.Deriving.Internal
 import           Data.List (partition)
+import qualified Data.List.NonEmpty as NE
+import           Data.List.NonEmpty (NonEmpty(..))
 import qualified Data.Map as Map
 import           Data.Map (Map)
 
@@ -277,10 +279,6 @@
         singleConType :: Bool
         singleConType = isSingleton cons
 
-        firstConName, lastConName :: Name
-        firstConName = constructorName $ head cons
-        lastConName  = constructorName $ last cons
-
         -- Alternatively, we could look these up from dataConTagMap, but this
         -- is slightly faster due to the lack of Map lookups.
         firstTag, lastTag :: Int
@@ -290,22 +288,30 @@
         dataConTagMap :: Map Name Int
         dataConTagMap = Map.fromList $ zip (map constructorName cons) [0..]
 
-        ordMatches :: ConstructorInfo -> Q Match
-        ordMatches = makeOrdFunForCon oFun v2 v2Hash tvMap singleConType
-                                      firstTag firstConName lastTag lastConName
-                                      dataConTagMap
-
         ordFunRhs :: Q Exp
-        ordFunRhs
-          | null cons
-          = conE eqDataName
+        ordFunRhs =
+          case cons of
+            [] -> conE eqDataName
+            c:cs -> ordFunRhsNonEmptyCons (c :| cs)
+
+        ordFunRhsNonEmptyCons :: NonEmpty ConstructorInfo -> Q Exp
+        ordFunRhsNonEmptyCons cs@(c :| _)
           | length nullaryCons <= 2
-          = caseE (varE v1) $ map ordMatches cons
+          = caseE (varE v1) $ map ordMatches $ NE.toList cs
           | null nonNullaryCons
           = mkTagCmp
           | otherwise
           = caseE (varE v1) $ map ordMatches nonNullaryCons
                 ++ [match wildP (normalB mkTagCmp) []]
+          where
+            firstConName, lastConName :: Name
+            firstConName = constructorName c
+            lastConName  = constructorName $ NE.last cs
+
+            ordMatches :: ConstructorInfo -> Q Match
+            ordMatches = makeOrdFunForCon oFun v2 v2Hash tvMap singleConType
+                                          firstTag firstConName lastTag lastConName
+                                          dataConTagMap
 
         mkTagCmp :: Q Exp
         mkTagCmp = untagExpr [(v1, v1Hash), (v2, v2Hash)] $
