diff --git a/Control/DeepSeq.hs b/Control/DeepSeq.hs
--- a/Control/DeepSeq.hs
+++ b/Control/DeepSeq.hs
@@ -1,234 +1,1156 @@
-#if __GLASGOW_HASKELL__ >= 703
-{-# LANGUAGE Safe #-}
-#endif
------------------------------------------------------------------------------
--- |
--- Module      :  Control.DeepSeq
--- Copyright   :  (c) The University of Glasgow 2001-2009
--- License     :  BSD-style (see the file LICENSE)
--- 
--- Maintainer  :  libraries@haskell.org
--- Stability   :  stable
--- Portability :  portable
---
--- This module provides an overloaded function, 'deepseq', for fully
--- evaluating data structures (that is, evaluating to \"Normal Form\").
---
--- A typical use is to prevent resource leaks in lazy IO programs, by
--- forcing all characters from a file to be read. For example:
---
--- > import System.IO
--- > import Control.DeepSeq
--- > 
--- > main = do
--- >     h <- openFile "f" ReadMode
--- >     s <- hGetContents h
--- >     s `deepseq` hClose h
--- >     return s
---
--- 'deepseq' differs from 'seq' as it traverses data structures deeply,
--- for example, 'seq' will evaluate only to the first constructor in
--- the list:
---
--- > > [1,2,undefined] `seq` 3
--- > 3
---
--- While 'deepseq' will force evaluation of all the list elements:
---
--- > > [1,2,undefined] `deepseq` 3
--- > *** Exception: Prelude.undefined
---
--- Another common use is to ensure any exceptions hidden within lazy
--- fields of a data structure do not leak outside the scope of the
--- exception handler, or to force evaluation of a data structure in one
--- thread, before passing to another thread (preventing work moving to
--- the wrong threads).
---
-module Control.DeepSeq (
-     deepseq, ($!!), force,
-     NFData(..),
-  ) where
-
-import Data.Int
-import Data.Word
-import Data.Ratio
-import Data.Complex
-import Data.Array
-import Data.Fixed
-import Data.Version
-
-infixr 0 $!!
-
--- | 'deepseq': fully evaluates the first argument, before returning the
--- second.
---
--- The name 'deepseq' is used to illustrate the relationship to 'seq':
--- where 'seq' is shallow in the sense that it only evaluates the top
--- level of its argument, 'deepseq' traverses the entire data structure
--- evaluating it completely.
---
--- 'deepseq' can be useful for forcing pending exceptions,
--- eradicating space leaks, or forcing lazy I/O to happen.  It is
--- also useful in conjunction with parallel Strategies (see the
--- @parallel@ package).
---
--- There is no guarantee about the ordering of evaluation.  The
--- implementation may evaluate the components of the structure in
--- any order or in parallel.  To impose an actual order on
--- evaluation, use 'pseq' from "Control.Parallel" in the
--- @parallel@ package.
---
-deepseq :: NFData a => a -> b -> b
-deepseq a b = rnf a `seq` b
-
--- | the deep analogue of '$!'.  In the expression @f $!! x@, @x@ is
--- fully evaluated before the function @f@ is applied to it.
-($!!) :: (NFData a) => (a -> b) -> a -> b
-f $!! x = x `deepseq` f x
-
--- | a variant of 'deepseq' that is useful in some circumstances:
---
--- > force x = x `deepseq` x
---
--- @force x@ fully evaluates @x@, and then returns it.  Note that
--- @force x@ only performs evaluation when the value of @force x@
--- itself is demanded, so essentially it turns shallow evaluation into
--- deep evaluation.
-
-force :: (NFData a) => a -> a
-force x = x `deepseq` x
-
--- | A class of types that can be fully evaluated.
-class NFData a where
-    -- | rnf should reduce its argument to normal form (that is, fully
-    -- evaluate all sub-components), and then return '()'.
-    -- 
-    -- The default implementation of 'rnf' is 
-    --
-    -- > rnf a = a `seq` ()
-    -- 
-    -- which may be convenient when defining instances for data types with
-    -- no unevaluated fields (e.g. enumerations).
-    rnf :: a -> ()
-    rnf a = a `seq` ()
-
-instance NFData Int 
-instance NFData Word
-instance NFData Integer
-instance NFData Float
-instance NFData Double
-
-instance NFData Char
-instance NFData Bool
-instance NFData ()
-
-instance NFData Int8
-instance NFData Int16
-instance NFData Int32
-instance NFData Int64
-
-instance NFData Word8
-instance NFData Word16
-instance NFData Word32
-instance NFData Word64
-
-instance NFData (Fixed a)
-
--- |This instance is for convenience and consistency with 'seq'.
--- This assumes that WHNF is equivalent to NF for functions.
-instance NFData (a -> b)
-
---Rational and complex numbers.
-
-instance (Integral a, NFData a) => NFData (Ratio a) where
-  rnf x = rnf (numerator x, denominator x)
-
-instance (RealFloat a, NFData a) => NFData (Complex a) where
-  rnf (x:+y) = rnf x `seq` 
-               rnf y `seq`
-               ()
-
-instance NFData a => NFData (Maybe a) where
-    rnf Nothing  = ()
-    rnf (Just x) = rnf x
-
-instance (NFData a, NFData b) => NFData (Either a b) where
-    rnf (Left x)  = rnf x
-    rnf (Right y) = rnf y
-
-instance NFData Data.Version.Version where
-    rnf (Data.Version.Version branch tags) = rnf branch `seq` rnf tags
-
-instance NFData a => NFData [a] where
-    rnf [] = ()
-    rnf (x:xs) = rnf x `seq` rnf xs
-
-instance (Ix a, NFData a, NFData b) => NFData (Array a b) where
-    rnf x = rnf (bounds x, Data.Array.elems x)
-
-instance (NFData a, NFData b) => NFData (a,b) where
-  rnf (x,y) = rnf x `seq` rnf y
-
-instance (NFData a, NFData b, NFData c) => NFData (a,b,c) where
-  rnf (x,y,z) = rnf x `seq` rnf y `seq` rnf z 
-
-instance (NFData a, NFData b, NFData c, NFData d) => NFData (a,b,c,d) where
-  rnf (x1,x2,x3,x4) = rnf x1 `seq` 
-		        rnf x2 `seq` 
-		        rnf x3 `seq` 
-		        rnf x4 
-
-instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) => 
-         NFData (a1, a2, a3, a4, a5) where
-  rnf (x1, x2, x3, x4, x5) =
-                  rnf x1 `seq`
-                  rnf x2 `seq`
-                  rnf x3 `seq`
-                  rnf x4 `seq`
-                  rnf x5
-
-instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) => 
-         NFData (a1, a2, a3, a4, a5, a6) where
-  rnf (x1, x2, x3, x4, x5, x6) =
-                  rnf x1 `seq`
-                  rnf x2 `seq`
-                  rnf x3 `seq`
-                  rnf x4 `seq`
-                  rnf x5 `seq`
-                  rnf x6
-
-instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) => 
-         NFData (a1, a2, a3, a4, a5, a6, a7) where
-  rnf (x1, x2, x3, x4, x5, x6, x7) =
-                  rnf x1 `seq`
-                  rnf x2 `seq`
-                  rnf x3 `seq`
-                  rnf x4 `seq`
-                  rnf x5 `seq`
-                  rnf x6 `seq`
-                  rnf x7
-
-instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) => 
-         NFData (a1, a2, a3, a4, a5, a6, a7, a8) where
-  rnf (x1, x2, x3, x4, x5, x6, x7, x8) =
-                  rnf x1 `seq`
-                  rnf x2 `seq`
-                  rnf x3 `seq`
-                  rnf x4 `seq`
-                  rnf x5 `seq`
-                  rnf x6 `seq`
-                  rnf x7 `seq`
-                  rnf x8
-
-instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8, NFData a9) => 
-         NFData (a1, a2, a3, a4, a5, a6, a7, a8, a9) where
-  rnf (x1, x2, x3, x4, x5, x6, x7, x8, x9) =
-                  rnf x1 `seq`
-                  rnf x2 `seq`
-                  rnf x3 `seq`
-                  rnf x4 `seq`
-                  rnf x5 `seq`
-                  rnf x6 `seq`
-                  rnf x7 `seq`
-                  rnf x8 `seq`
-                  rnf x9
+{-# LANGUAGE CPP #-}
+{-# LANGUAGE DefaultSignatures #-}
+{-# LANGUAGE EmptyCase #-}
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE PolyKinds #-}
+{-# LANGUAGE QuantifiedConstraints #-}
+{-# LANGUAGE Trustworthy #-}
+{-# LANGUAGE TypeFamilies #-}
+{-# LANGUAGE TypeOperators #-}
+
+#if __GLASGOW_HASKELL__ >= 811 && __GLASGOW_HASKELL__ < 901
+-- For the Option instance (https://gitlab.haskell.org/ghc/ghc/issues/15028)
+{-# OPTIONS_GHC -Wno-deprecations #-}
+#endif
+
+-----------------------------------------------------------------------------
+
+-- |
+-- Module      :  Control.DeepSeq
+-- Copyright   :  (c) The University of Glasgow 2001-2009
+-- License     :  BSD-style (see the file LICENSE)
+--
+-- Maintainer  :  libraries@haskell.org
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- This module provides overloaded functions, such as 'deepseq' and
+-- 'rnf', for fully evaluating data structures (that is, evaluating to
+-- \"Normal Form\").
+--
+-- A typical use is to prevent resource leaks in lazy IO programs, by
+-- forcing all characters from a file to be read. For example:
+--
+-- > import System.IO
+-- > import Control.DeepSeq
+-- > import Control.Exception (evaluate)
+-- >
+-- > readFile' :: FilePath -> IO String
+-- > readFile' fn = do
+-- >     h <- openFile fn ReadMode
+-- >     s <- hGetContents h
+-- >     evaluate (rnf s)
+-- >     hClose h
+-- >     return s
+--
+-- __Note__: The example above should rather be written in terms of
+-- 'Control.Exception.bracket' to ensure releasing file-descriptors in
+-- a timely matter (see the description of 'force' for an example).
+--
+-- 'deepseq' differs from 'seq' as it traverses data structures deeply,
+-- for example, 'seq' will evaluate only to the first constructor in
+-- the list:
+--
+-- > > [1,2,undefined] `seq` 3
+-- > 3
+--
+-- While 'deepseq' will force evaluation of all the list elements:
+--
+-- > > [1,2,undefined] `deepseq` 3
+-- > *** Exception: Prelude.undefined
+--
+-- Another common use is to ensure any exceptions hidden within lazy
+-- fields of a data structure do not leak outside the scope of the
+-- exception handler, or to force evaluation of a data structure in one
+-- thread, before passing to another thread (preventing work moving to
+-- the wrong threads).
+--
+-- @since 1.1.0.0
+module Control.DeepSeq (
+  -- * 'NFData' class
+  NFData (rnf),
+
+  -- * Helper functions
+  deepseq,
+  force,
+  ($!!),
+  (<$!!>),
+  rwhnf,
+  Unit(..),
+
+  -- * Liftings of the 'NFData' class
+
+  -- ** For unary constructors
+  NFData1 (liftRnf),
+  rnf1,
+
+  -- ** For binary constructors
+  NFData2 (liftRnf2),
+  rnf2,
+) where
+
+import Control.Applicative
+import Control.Concurrent (MVar, ThreadId)
+import Control.Exception (MaskingState (..))
+import Data.Complex
+import Data.Fixed
+import Data.Functor.Compose
+import Data.Functor.Identity (Identity (..))
+import qualified Data.Functor.Product as Functor
+import qualified Data.Functor.Sum as Functor
+import Data.IORef
+import Data.Int
+import Data.List.NonEmpty (NonEmpty (..))
+import Data.Monoid as Mon
+import Data.Ord (Down (Down))
+import Data.Proxy (Proxy (Proxy))
+import Data.Ratio
+import Data.STRef
+import Data.Semigroup as Semi
+import Data.Type.Equality ((:~:), (:~~:))
+import Data.Typeable (TyCon, TypeRep, rnfTyCon, rnfTypeRep)
+import Data.Unique (Unique)
+import Data.Version
+import Data.Void (Void, absurd)
+import Data.Word
+import Foreign.C.Types
+import Foreign.Ptr
+import GHC.Arr (Array)
+import qualified GHC.Arr
+import GHC.Fingerprint.Type (Fingerprint (..))
+import GHC.Generics
+import GHC.Stack.Types (CallStack (..), SrcLoc (..))
+import Numeric.Natural (Natural)
+import System.Exit (ExitCode (..))
+import System.Mem.StableName (StableName)
+import qualified Type.Reflection as Reflection
+
+#ifdef MIN_VERSION_ghc_prim
+#if MIN_VERSION_ghc_prim(0,7,0)
+import GHC.Tuple (Solo (..))
+#endif
+#endif
+
+#if MIN_VERSION_base(4,17,0)
+import Data.Array.Byte (ByteArray(..), MutableByteArray(..))
+#endif
+
+-- | Hidden internal type-class
+class GNFData arity f where
+  grnf :: RnfArgs arity a -> f a -> ()
+
+instance GNFData arity V1 where
+  grnf _ x = case x of {}
+
+data Zero
+
+data One
+
+data family RnfArgs arity a
+
+data instance RnfArgs Zero a = RnfArgs0
+
+newtype instance RnfArgs One a = RnfArgs1 (a -> ())
+
+instance GNFData arity U1 where
+  grnf _ U1 = ()
+
+instance NFData a => GNFData arity (K1 i a) where
+  grnf _ = rnf . unK1
+  {-# INLINEABLE grnf #-}
+
+instance GNFData arity a => GNFData arity (M1 i c a) where
+  grnf args = grnf args . unM1
+  {-# INLINEABLE grnf #-}
+
+instance GNFData arity (URec a) where
+  grnf _ = rwhnf -- Every URec data instance consists of a single data
+  -- constructor containing a single strict field, so reducing
+  -- any URec instance to WHNF suffices to reduce it to NF.
+  {-# INLINEABLE grnf #-}
+
+instance (GNFData arity a, GNFData arity b) => GNFData arity (a :*: b) where
+  grnf args (x :*: y) = grnf args x `seq` grnf args y
+  {-# INLINEABLE grnf #-}
+
+instance (GNFData arity a, GNFData arity b) => GNFData arity (a :+: b) where
+  grnf args (L1 x) = grnf args x
+  grnf args (R1 x) = grnf args x
+  {-# INLINEABLE grnf #-}
+
+instance GNFData One Par1 where
+  grnf (RnfArgs1 r) = r . unPar1
+
+instance NFData1 f => GNFData One (Rec1 f) where
+  grnf (RnfArgs1 r) = liftRnf r . unRec1
+
+instance (NFData1 f, GNFData One g) => GNFData One (f :.: g) where
+  grnf args = liftRnf (grnf args) . unComp1
+
+infixr 0 $!!
+
+infixr 0 `deepseq`
+
+-- | 'deepseq': fully evaluates the first argument, before returning the
+-- second.
+--
+-- The name 'deepseq' is used to illustrate the relationship to 'seq':
+-- where 'seq' is shallow in the sense that it only evaluates the top
+-- level of its argument, 'deepseq' traverses the entire data structure
+-- evaluating it completely.
+--
+-- 'deepseq' can be useful for forcing pending exceptions,
+-- eradicating space leaks, or forcing lazy I/O to happen.  It is
+-- also useful in conjunction with parallel Strategies (see the
+-- @parallel@ package).
+--
+-- There is no guarantee about the ordering of evaluation.  The
+-- implementation may evaluate the components of the structure in
+-- any order or in parallel.  To impose an actual order on
+-- evaluation, use 'pseq' from "Control.Parallel" in the
+-- @parallel@ package.
+--
+-- @since 1.1.0.0
+deepseq :: NFData a => a -> b -> b
+deepseq a b = rnf a `seq` b
+
+-- | The deep analogue of '$!'.  @f $!! x@ fully evaluates @x@
+-- before returning @f x@.
+--
+-- There is no guarantee about the ordering of evaluation.
+-- @f x@ may be evaluated before @x@ is fully evaluated.
+-- To impose an actual order on evaluation, use 'pseq' from
+-- "Control.Parallel" in the @parallel@ package.
+--
+-- @since 1.2.0.0
+($!!) :: (NFData a) => (a -> b) -> a -> b
+f $!! x = x `deepseq` f x
+
+-- | A variant of 'deepseq' that is useful in some circumstances:
+--
+-- > force x = x `deepseq` x
+--
+-- @force x@ fully evaluates @x@, and then returns it.  Note that
+-- @force x@ only performs evaluation when the value of @force x@
+-- itself is demanded, so essentially it turns shallow evaluation into
+-- deep evaluation.
+--
+-- 'force' can be conveniently used in combination with @ViewPatterns@:
+--
+-- > {-# LANGUAGE BangPatterns, ViewPatterns #-}
+-- > import Control.DeepSeq
+-- >
+-- > someFun :: ComplexData -> SomeResult
+-- > someFun (force -> !arg) = {- 'arg' will be fully evaluated -}
+--
+-- Another useful application is to combine 'force' with
+-- 'Control.Exception.evaluate' in order to force deep evaluation
+-- relative to other 'IO' operations:
+--
+-- > import Control.Exception (evaluate)
+-- > import Control.DeepSeq
+-- >
+-- > main = do
+-- >   result <- evaluate $ force $ pureComputation
+-- >   {- 'result' will be fully evaluated at this point -}
+-- >   return ()
+--
+-- Finally, here's an exception safe variant of the @readFile'@ example:
+--
+-- > readFile' :: FilePath -> IO String
+-- > readFile' fn = bracket (openFile fn ReadMode) hClose $ \h ->
+-- >                        evaluate . force =<< hGetContents h
+--
+-- @since 1.2.0.0
+force :: (NFData a) => a -> a
+force x = x `deepseq` x
+
+-- | Deeply strict version of 'Control.Applicative.<$>'.
+--
+-- @since 1.4.3.0
+(<$!!>) :: (Monad m, NFData b) => (a -> b) -> m a -> m b
+f <$!!> m = m >>= \x -> pure $!! f x
+
+infixl 4 <$!!>
+
+-- | Reduce to weak head normal form
+--
+-- Equivalent to @\\x -> 'seq' x ()@.
+--
+-- Useful for defining 'NFData' for types for which NF=WHNF holds.
+--
+-- > data T = C1 | C2 | C3
+-- > instance NFData T where rnf = rwhnf
+--
+-- @since 1.4.3.0
+rwhnf :: a -> ()
+rwhnf = (`seq` ())
+{-# INLINE rwhnf #-}
+
+-- Note: the 'rwhnf' is defined point-free to help aggressive inlining
+
+-- | A class of types that can be fully evaluated.
+--
+-- @since 1.1.0.0
+class NFData a where
+  -- | 'rnf' should reduce its argument to normal form (that is, fully
+  -- evaluate all sub-components), and then return '()'.
+  --
+  -- === 'Generic' 'NFData' deriving
+  --
+  -- Starting with GHC 7.2, you can automatically derive instances
+  -- for types possessing a 'Generic' instance.
+  --
+  -- Note: 'Generic1' can be auto-derived starting with GHC 7.4
+  --
+  -- > {-# LANGUAGE DeriveGeneric #-}
+  -- >
+  -- > import GHC.Generics (Generic, Generic1)
+  -- > import Control.DeepSeq
+  -- >
+  -- > data Foo a = Foo a String
+  -- >              deriving (Eq, Generic, Generic1)
+  -- >
+  -- > instance NFData a => NFData (Foo a)
+  -- > instance NFData1 Foo
+  -- >
+  -- > data Colour = Red | Green | Blue
+  -- >               deriving Generic
+  -- >
+  -- > instance NFData Colour
+  --
+  -- Starting with GHC 7.10, the example above can be written more
+  -- concisely by enabling the new @DeriveAnyClass@ extension:
+  --
+  -- > {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
+  -- >
+  -- > import GHC.Generics (Generic)
+  -- > import Control.DeepSeq
+  -- >
+  -- > data Foo a = Foo a String
+  -- >              deriving (Eq, Generic, Generic1, NFData, NFData1)
+  -- >
+  -- > data Colour = Red | Green | Blue
+  -- >               deriving (Generic, NFData)
+  -- >
+  --
+  -- === Compatibility with previous @deepseq@ versions
+  --
+  -- Prior to version 1.4.0.0, the default implementation of the 'rnf'
+  -- method was defined as
+  --
+  -- @'rnf' a = 'seq' a ()@
+  --
+  -- However, starting with @deepseq-1.4.0.0@, the default
+  -- implementation is based on @DefaultSignatures@ allowing for
+  -- more accurate auto-derived 'NFData' instances. If you need the
+  -- previously used exact default 'rnf' method implementation
+  -- semantics, use
+  --
+  -- > instance NFData Colour where rnf x = seq x ()
+  --
+  -- or alternatively
+  --
+  -- > instance NFData Colour where rnf = rwhnf
+  --
+  -- or
+  --
+  -- > {-# LANGUAGE BangPatterns #-}
+  -- > instance NFData Colour where rnf !_ = ()
+  rnf :: a -> ()
+  default rnf :: (Generic a, GNFData Zero (Rep a)) => a -> ()
+  rnf = grnf RnfArgs0 . from
+
+-- | A class of functors that can be fully evaluated.
+--
+-- In `deepseq-1.5.0.0` this class was updated to include superclasses.
+--
+-- @since 1.4.3.0
+class (forall a. NFData a => NFData (f a)) => NFData1 f where
+  -- | 'liftRnf' should reduce its argument to normal form (that is, fully
+  -- evaluate all sub-components), given an argument to reduce @a@ arguments,
+  -- and then return '()'.
+  --
+  -- See 'rnf' for the generic deriving.
+  liftRnf :: (a -> ()) -> f a -> ()
+  default liftRnf :: (Generic1 f, GNFData One (Rep1 f)) => (a -> ()) -> f a -> ()
+  liftRnf r = grnf (RnfArgs1 r) . from1
+
+-- | Lift the standard 'rnf' function through the type constructor.
+--
+-- @since 1.4.3.0
+rnf1 :: (NFData1 f, NFData a) => f a -> ()
+rnf1 = liftRnf rnf
+
+-- | A class of bifunctors that can be fully evaluated.
+--
+-- In `deepseq-1.5.0.0` this class was updated to include superclasses.
+--
+-- @since 1.4.3.0
+class (forall a. NFData a => NFData1 (p a)) => NFData2 p where
+  -- | 'liftRnf2' should reduce its argument to normal form (that
+  -- is, fully evaluate all sub-components), given functions to
+  -- reduce @a@ and @b@ arguments respectively, and then return '()'.
+  --
+  -- __Note__: Unlike for the unary 'liftRnf', there is currently no
+  -- support for generically deriving 'liftRnf2'.
+  liftRnf2 :: (a -> ()) -> (b -> ()) -> p a b -> ()
+
+-- | Lift the standard 'rnf' function through the type constructor.
+--
+-- @since 1.4.3.0
+rnf2 :: (NFData2 p, NFData a, NFData b) => p a b -> ()
+rnf2 = liftRnf2 rnf rnf
+
+-- | A monoid with @(<>) = seq@.
+--
+-- Its purpose is to allow reducing structures to normal form using
+-- 'foldMap'-like functions.
+--
+-- ==== __Examples__
+--
+-- @
+-- data Three a = Three a a a
+--
+-- instance Foldable Three where
+--   foldMap f (Three x1 x2 x3) = f x1 <> f x2 <> f x3
+--
+-- instance NFData a => NFData (Three a) where
+--   rnf = runUnit . foldMap (Unit . rnf)
+-- @
+--
+-- @
+-- data Tree a b
+--   = NodeA a [Tree a b]
+--   | NodeB b [Tree a b]
+--
+-- foldMapTree :: Monoid m => (a -> m) -> (b -> m) -> Tree a b -> m
+-- foldMapTree f g = go
+--   where
+--     go (NodeA x ts) = f x <> foldMap go ts
+--     go (NodeB y ts) = g y <> foldMap go ts
+--
+-- instance NFData2 Tree where
+--   liftRnf2 r r' = runUnit . foldMapTree (Unit . r) (Unit . r')
+-- @
+newtype Unit = Unit { runUnit :: () }
+
+instance Semigroup Unit where
+  (<>) = seq
+
+instance Monoid Unit where
+  mempty = Unit ()
+
+instance NFData Int where rnf = rwhnf
+
+instance NFData Word where rnf = rwhnf
+
+instance NFData Integer where rnf = rwhnf
+
+instance NFData Float where rnf = rwhnf
+
+instance NFData Double where rnf = rwhnf
+
+instance NFData Char where rnf = rwhnf
+
+instance NFData Bool where rnf = rwhnf
+
+instance NFData Ordering where rnf = rwhnf
+
+instance NFData () where rnf = rwhnf
+
+instance NFData Int8 where rnf = rwhnf
+
+instance NFData Int16 where rnf = rwhnf
+
+instance NFData Int32 where rnf = rwhnf
+
+instance NFData Int64 where rnf = rwhnf
+
+instance NFData Word8 where rnf = rwhnf
+
+instance NFData Word16 where rnf = rwhnf
+
+instance NFData Word32 where rnf = rwhnf
+
+instance NFData Word64 where rnf = rwhnf
+
+-- | @since 1.4.4.0
+instance NFData MaskingState where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData (Proxy a) where rnf Proxy = ()
+
+-- | @since 1.4.3.0
+instance NFData1 Proxy where liftRnf _ Proxy = ()
+
+-- | @since 1.4.3.0
+instance NFData (a :~: b) where rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 ((:~:) a) where liftRnf _ = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData2 (:~:) where liftRnf2 _ _ = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData (a :~~: b) where rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 ((:~~:) a) where liftRnf _ = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData2 (:~~:) where liftRnf2 _ _ = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Identity a) where
+  rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Identity where
+  liftRnf r = r . runIdentity
+
+-- | Defined as @'rnf' = 'absurd'@.
+--
+-- @since 1.4.0.0
+instance NFData Void where
+  rnf = absurd
+
+-- | @since 1.4.0.0
+instance NFData Natural where rnf = rwhnf
+
+-- | @since 1.3.0.0
+instance NFData (Fixed a) where rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 Fixed where liftRnf _ = rwhnf
+
+-- | This instance is for convenience and consistency with 'seq'.
+--  This assumes that WHNF is equivalent to NF for functions.
+--
+--  @since 1.3.0.0
+instance NFData (a -> b) where rnf = rwhnf
+
+-- Rational and complex numbers.
+
+-- | Available on @base >=4.9@
+--
+-- @since 1.4.3.0
+instance NFData1 Ratio where
+  liftRnf r x = r (numerator x) `seq` r (denominator x)
+
+-- | @since 1.4.3.0
+instance (NFData1 f, NFData1 g) => NFData1 (Compose f g) where
+  liftRnf r = liftRnf (liftRnf r) . getCompose
+
+-- | Note: in @deepseq-1.5.0.0@ this instance's superclasses were changed.
+-- 
+-- @since 1.4.3.0
+instance (NFData (f (g a))) => NFData (Compose f g a) where
+  rnf (Compose fga) = rnf fga
+
+-- | @since 1.4.3.0
+instance (NFData1 f, NFData1 g) => NFData1 (Functor.Sum f g) where
+  liftRnf rnf0 (Functor.InL l) = liftRnf rnf0 l
+  liftRnf rnf0 (Functor.InR r) = liftRnf rnf0 r
+
+-- | Note: in @deepseq-1.5.0.0@ this instance's superclasses were changed.
+-- 
+-- @since 1.4.3.0
+instance (NFData (f a), NFData (g a)) => NFData (Functor.Sum f g a) where
+  rnf (Functor.InL fa) = rnf fa
+  rnf (Functor.InR ga) = rnf ga
+
+-- | @since 1.4.3.0
+instance (NFData1 f, NFData1 g) => NFData1 (Functor.Product f g) where
+  liftRnf rnf0 (Functor.Pair f g) = liftRnf rnf0 f `seq` liftRnf rnf0 g
+
+-- | Note: in @deepseq-1.5.0.0@ this instance's superclasses were changed.
+-- 
+-- @since 1.4.3.0
+instance (NFData (f a), NFData (g a)) => NFData (Functor.Product f g a) where
+  rnf (Functor.Pair fa ga) = rnf fa `seq` rnf ga
+
+instance NFData a => NFData (Ratio a) where
+  rnf x = rnf (numerator x, denominator x)
+
+instance (NFData a) => NFData (Complex a) where
+  rnf (x :+ y) = rnf x `seq` rnf y `seq` ()
+
+instance NFData a => NFData (Maybe a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Maybe where
+  liftRnf _r Nothing = ()
+  liftRnf r (Just x) = r x
+
+instance (NFData a, NFData b) => NFData (Either a b) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance (NFData a) => NFData1 (Either a) where liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance NFData2 Either where
+  liftRnf2 l _r (Left x) = l x
+  liftRnf2 _l r (Right y) = r y
+
+-- | @since 1.3.0.0
+instance NFData Data.Version.Version where
+  rnf (Data.Version.Version branch tags) = rnf branch `seq` rnf tags
+
+instance NFData a => NFData [a] where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 [] where
+  liftRnf f = foldr (\x r -> f x `seq` r) ()
+  {-# INLINABLE liftRnf #-}
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (ZipList a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 ZipList where
+  liftRnf r = liftRnf r . getZipList
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Const a b) where
+  rnf = rnf . getConst
+
+-- | @since 1.4.3.0
+instance NFData a => NFData1 (Const a) where
+  liftRnf _ = rnf . getConst
+
+-- | @since 1.4.3.0
+instance NFData2 Const where
+  liftRnf2 r _ = r . getConst
+
+-- We should use MIN_VERSION array(0,5,1,1) but that's not possible.
+-- There isn't an underscore to not break C preprocessor
+instance (NFData a, NFData b) => NFData (Array a b) where
+  rnf x = rnf (GHC.Arr.bounds x, GHC.Arr.elems x)
+
+-- | @since 1.4.3.0
+instance (NFData a) => NFData1 (Array a) where
+  liftRnf r x = rnf (GHC.Arr.bounds x) `seq` liftRnf r (GHC.Arr.elems x)
+
+-- | @since 1.4.3.0
+instance NFData2 Array where
+  liftRnf2 r r' x =
+    liftRnf2 r r (GHC.Arr.bounds x) `seq` liftRnf r' (GHC.Arr.elems x)
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Down a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Down where
+  liftRnf r (Down x) = r x
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Dual a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Dual where
+  liftRnf r (Dual x) = r x
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Mon.First a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Mon.First where
+  liftRnf r (Mon.First x) = liftRnf r x
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Mon.Last a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Mon.Last where
+  liftRnf r (Mon.Last x) = liftRnf r x
+
+-- | @since 1.4.0.0
+instance NFData Any where rnf = rnf . getAny
+
+-- | @since 1.4.0.0
+instance NFData All where rnf = rnf . getAll
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Sum a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Sum where
+  liftRnf r (Sum x) = r x
+
+-- | @since 1.4.0.0
+instance NFData a => NFData (Product a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Product where
+  liftRnf r (Product x) = r x
+
+-- | @since 1.4.0.0
+instance NFData (StableName a) where
+  rnf = rwhnf -- assumes `data StableName a = StableName (StableName# a)`
+
+-- | @since 1.4.3.0
+instance NFData1 StableName where
+  liftRnf _ = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData ThreadId where
+  rnf = rwhnf -- assumes `data ThreadId = ThreadId ThreadId#`
+
+-- | @since 1.4.0.0
+instance NFData Unique where
+  rnf = rwhnf -- assumes `newtype Unique = Unique Integer`
+
+-- | __NOTE__: Prior to @deepseq-1.4.4.0@ this instance was only defined for @base-4.8.0.0@ and later.
+--
+-- @since 1.4.0.0
+instance NFData TypeRep where
+  rnf tyrep = rnfTypeRep tyrep
+
+-- | __NOTE__: Prior to @deepseq-1.4.4.0@ this instance was only defined for @base-4.8.0.0@ and later.
+--
+-- @since 1.4.0.0
+instance NFData TyCon where
+  rnf tycon = rnfTyCon tycon
+
+-- | @since 1.4.8.0
+instance NFData (Reflection.TypeRep a) where
+  rnf tr = Reflection.rnfTypeRep tr
+
+-- | @since 1.4.8.0
+instance NFData Reflection.Module where
+  rnf modul = Reflection.rnfModule modul
+
+-- | __NOTE__: Only strict in the reference and not the referenced value.
+--
+-- @since 1.4.2.0
+instance NFData (IORef a) where
+  rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 IORef where
+  liftRnf _ = rwhnf
+
+-- | __NOTE__: Only strict in the reference and not the referenced value.
+--
+-- @since 1.4.2.0
+instance NFData (STRef s a) where
+  rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 (STRef s) where
+  liftRnf _ = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData2 STRef where
+  liftRnf2 _ _ = rwhnf
+
+-- | __NOTE__: Only strict in the reference and not the referenced value.
+--
+-- @since 1.4.2.0
+instance NFData (MVar a) where
+  rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 MVar where
+  liftRnf _ = rwhnf
+
+----------------------------------------------------------------------------
+-- GHC Specifics
+
+-- | @since 1.4.0.0
+instance NFData Fingerprint where
+  rnf (Fingerprint _ _) = ()
+
+----------------------------------------------------------------------------
+-- Foreign.Ptr
+
+-- | @since 1.4.2.0
+instance NFData (Ptr a) where
+  rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 Ptr where
+  liftRnf _ = rwhnf
+
+-- | @since 1.4.2.0
+instance NFData (FunPtr a) where
+  rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData1 FunPtr where
+  liftRnf _ = rwhnf
+
+----------------------------------------------------------------------------
+-- Foreign.C.Types
+
+-- | @since 1.4.0.0
+instance NFData CChar where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CSChar where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUChar where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CShort where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUShort where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CInt where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUInt where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CLong where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CULong where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CPtrdiff where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CSize where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CWchar where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CSigAtomic where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CLLong where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CULLong where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CIntPtr where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUIntPtr where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CIntMax where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUIntMax where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CClock where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CTime where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CUSeconds where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CSUSeconds where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CFloat where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CDouble where rnf = rwhnf
+
+-- NOTE: The types `CFile`, `CFPos`, and `CJmpBuf` below are not
+-- newtype wrappers rather defined as field-less single-constructor
+-- types.
+
+-- | @since 1.4.0.0
+instance NFData CFile where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CFpos where rnf = rwhnf
+
+-- | @since 1.4.0.0
+instance NFData CJmpBuf where rnf = rwhnf
+
+-- | @since 1.4.3.0
+instance NFData CBool where rnf = rwhnf
+
+----------------------------------------------------------------------------
+-- System.Exit
+
+-- | @since 1.4.2.0
+instance NFData ExitCode where
+  rnf (ExitFailure n) = rnf n
+  rnf ExitSuccess = ()
+
+----------------------------------------------------------------------------
+-- instances previously provided by semigroups package
+
+-- | @since 1.4.2.0
+instance NFData a => NFData (NonEmpty a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 NonEmpty where
+  liftRnf r (x :| xs) = r x `seq` liftRnf r xs
+
+-- | @since 1.4.2.0
+instance NFData a => NFData (Min a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Min where
+  liftRnf r (Min a) = r a
+
+-- | @since 1.4.2.0
+instance NFData a => NFData (Max a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Max where
+  liftRnf r (Max a) = r a
+
+-- | @since 1.4.2.0
+instance (NFData a, NFData b) => NFData (Arg a b) where rnf = rnf2
+
+-- | @since 1.4.3.0
+instance (NFData a) => NFData1 (Arg a) where liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance NFData2 Arg where
+  liftRnf2 r r' (Arg a b) = r a `seq` r' b `seq` ()
+
+-- | @since 1.4.2.0
+instance NFData a => NFData (Semi.First a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Semi.First where
+  liftRnf r (Semi.First a) = r a
+
+-- | @since 1.4.2.0
+instance NFData a => NFData (Semi.Last a) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 Semi.Last where
+  liftRnf r (Semi.Last a) = r a
+
+-- | @since 1.4.2.0
+instance NFData m => NFData (WrappedMonoid m) where rnf = rnf1
+
+-- | @since 1.4.3.0
+instance NFData1 WrappedMonoid where
+  liftRnf r (WrapMonoid a) = r a
+
+#if __GLASGOW_HASKELL__ < 901
+-- |@since 1.4.2.0
+instance NFData a => NFData (Option a) where rnf = rnf1
+-- |@since 1.4.3.0
+instance NFData1 Option where
+  liftRnf r (Option a) = liftRnf r a
+#endif
+
+----------------------------------------------------------------------------
+-- GHC.Stack
+
+-- | @since 1.4.2.0
+instance NFData SrcLoc where
+  rnf (SrcLoc a b c d e f g) =
+    rnf a `seq` rnf b `seq` rnf c `seq` rnf d `seq` rnf e `seq` rnf f `seq` rnf g
+
+-- | @since 1.4.2.0
+instance NFData CallStack where
+  rnf EmptyCallStack = ()
+  rnf (PushCallStack a b c) = rnf a `seq` rnf b `seq` rnf c
+  rnf (FreezeCallStack a) = rnf a
+
+----------------------------------------------------------------------------
+-- Tuples
+
+#ifdef MIN_VERSION_ghc_prim
+#if MIN_VERSION_ghc_prim(0,7,0)
+-- |@since 1.4.6.0
+instance NFData a => NFData (Solo a) where
+#if MIN_VERSION_ghc_prim(0,10,0)
+  rnf (MkSolo a) = rnf a
+#else
+  rnf (Solo a) = rnf a
+#endif
+-- |@since 1.4.6.0
+instance NFData1 Solo where
+#if MIN_VERSION_ghc_prim(0,10,0)
+  liftRnf r (MkSolo a) = r a
+#else
+  liftRnf r (Solo a) = r a
+#endif
+#endif
+#endif
+
+instance (NFData a, NFData b) => NFData (a, b) where rnf = rnf2
+
+-- | @since 1.4.3.0
+instance (NFData a) => NFData1 ((,) a) where liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance NFData2 (,) where
+  liftRnf2 r r' (x, y) = r x `seq` r' y
+
+-- Code below is generated, see generate-nfdata-tuple.hs
+instance
+  (NFData a1, NFData a2, NFData a3) =>
+  NFData (a1, a2, a3)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2) =>
+  NFData1 ((,,) a1 a2)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1) =>
+  NFData2 ((,,) a1)
+  where
+  liftRnf2 r r' (x1, x2, x3) =
+    rnf x1 `seq` r x2 `seq` r' x3
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4) =>
+  NFData (a1, a2, a3, a4)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3) =>
+  NFData1 ((,,,) a1 a2 a3)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2) =>
+  NFData2 ((,,,) a1 a2)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4) =
+    rnf x1 `seq` rnf x2 `seq` r x3 `seq` r' x4
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) =>
+  NFData (a1, a2, a3, a4, a5)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4) =>
+  NFData1 ((,,,,) a1 a2 a3 a4)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3) =>
+  NFData2 ((,,,,) a1 a2 a3)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4, x5) =
+    rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` r x4 `seq` r' x5
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) =>
+  NFData (a1, a2, a3, a4, a5, a6)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) =>
+  NFData1 ((,,,,,) a1 a2 a3 a4 a5)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4) =>
+  NFData2 ((,,,,,) a1 a2 a3 a4)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4, x5, x6) =
+    rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` r x5 `seq` r' x6
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) =>
+  NFData (a1, a2, a3, a4, a5, a6, a7)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) =>
+  NFData1 ((,,,,,,) a1 a2 a3 a4 a5 a6)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) =>
+  NFData2 ((,,,,,,) a1 a2 a3 a4 a5)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4, x5, x6, x7) =
+    rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` r x6 `seq` r' x7
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) =>
+  NFData (a1, a2, a3, a4, a5, a6, a7, a8)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) =>
+  NFData1 ((,,,,,,,) a1 a2 a3 a4 a5 a6 a7)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) =>
+  NFData2 ((,,,,,,,) a1 a2 a3 a4 a5 a6)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4, x5, x6, x7, x8) =
+    rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` r x7 `seq` r' x8
+
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8, NFData a9) =>
+  NFData (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+  where
+  rnf = rnf2
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7, NFData a8) =>
+  NFData1 ((,,,,,,,,) a1 a2 a3 a4 a5 a6 a7 a8)
+  where
+  liftRnf = liftRnf2 rnf
+
+-- | @since 1.4.3.0
+instance
+  (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6, NFData a7) =>
+  NFData2 ((,,,,,,,,) a1 a2 a3 a4 a5 a6 a7)
+  where
+  liftRnf2 r r' (x1, x2, x3, x4, x5, x6, x7, x8, x9) =
+    rnf x1 `seq` rnf x2 `seq` rnf x3 `seq` rnf x4 `seq` rnf x5 `seq` rnf x6 `seq` rnf x7 `seq` r x8 `seq` r' x9
+
+----------------------------------------------------------------------------
+-- ByteArray
+
+#if MIN_VERSION_base(4,17,0)
+-- |@since 1.4.7.0
+instance NFData ByteArray where
+  rnf (ByteArray _) = ()
+
+-- |@since 1.4.8.0
+instance NFData (MutableByteArray s) where
+  rnf (MutableByteArray _) = ()
+#endif
diff --git a/changelog.md b/changelog.md
new file mode 100644
--- /dev/null
+++ b/changelog.md
@@ -0,0 +1,229 @@
+# Changelog for [`deepseq` package](http://hackage.haskell.org/package/deepseq)
+
+## Upcoming
+
+
+
+## 1.6.0.0
+
+  * Add Unit monoid with `seq`
+    ([#18](https://github.com/haskell/deepseq/issues/18), [#105](https://github.com/haskell/deepseq/issues/105))
+  * Drop the dependency on `array`
+    ([#102](https://github.com/haskell/deepseq/issues/102), [#107](https://github.com/haskell/deepseq/issues/107))
+
+## 1.5.0.0
+
+  * Add quantified superclasses to NFData(1,2)
+    ([#88](https://github.com/haskell/deepseq/issues/88))
+  * Alter superclasses for Data.Functor.{Sum, Product}
+    ([#95])(https://github.com/haskell/deepseq/pull/95)
+  * Drop support for GHC < 8.6
+    ([#94](https://github.com/haskell/deepseq/pull/94))
+  * List fusion in `instance NFData [a]` reduces allocations
+    ([#99](https://github.com/haskell/deepseq/pull/99))
+
+## 1.4.8.1
+
+  * Adapt the rename of the Solo constructor to MkSolo
+    ([#87](https://github.com/haskell/deepseq/pull/87))
+  * Add instances for the indexed `TypeRep`, along with `Module`.
+    ([#83](https://github.com/haskell/deepseq/pull/83))
+
+## 1.4.8.0
+
+  * Add `NFData` instance for `MutableByteArray`
+    ([#84](https://github.com/haskell/deepseq/pull/84))
+  * Change RnfArgs to be a data family
+    ([#85](https://github.com/haskell/deepseq/pull/85))
+
+## 1.4.7.0
+
+  * Add instances for `Solo` (GHC-9)
+    ([#69](https://github.com/haskell/deepseq/pull/69))
+  * Add once again `infixr 0 deepseq`
+    ([#56](https://github.com/haskell/deepseq/pull/56), [#74](https://github.com/haskell/deepseq/issues/74))
+  * Add `NFData` instance for `ByteArray`
+    ([#65](https://github.com/haskell/deepseq/pull/65))
+  * Drop support for GHC 7 to simplify CPP
+    ([#75](https://github.com/haskell/deepseq/pull/75))
+
+## 1.4.6.1
+
+  * Revert `infixr 0 deepseq`; this does not appear in the version of `deepseq` pinned to GHC 9.2.1
+
+## 1.4.6.0
+
+  * Bundled with GHC 9.2.1
+  * Remove instances for Data.Semigroup.Option for GHC >= 9.2
+    ([#62](https://github.com/haskell/deepseq/pull/62))
+  * Set the `infixr 0 deepseq` to be consistent with `seq`
+    ([#56](https://github.com/haskell/deepseq/pull/56))
+
+## 1.4.5.0
+
+  * Add `GNFData` for URec
+    This will enable deriving NFData instances for unboxed types
+
+## 1.4.4.0 *Sep 2018*
+
+  * Bundled with GHC 8.6.1
+
+  * Add `NFData` instance for `MaskingState`
+    ([#38](https://github.com/haskell/deepseq/pull/38))
+
+  * Define the `NFData` instances for `TypeRep` and `TyCon` on all supported
+    versions of `base`, not just 4.8 and later
+    ([#40](https://github.com/haskell/deepseq/pull/40))
+
+## 1.4.3.0 *Apr 2017*
+
+  * Bundled with GHC 8.2.1
+
+  * Drop support for GHC 7.0 & GHC 7.2
+
+  * Changed strictness behavior of generic `NFData` instances for
+    constructor-less data types. Before, a generic `rnf`
+    implementation would always `error` on a data type with no
+    constructors. Now, it will force the argument, so if the argument
+    is a diverging computation, a generic `rnf` implementation will
+    actually trigger the diverging computation.
+    ([#19](https://github.com/haskell/deepseq/issues/19))
+
+  * Add new `rwhnf` function defined as `rwhnf !_ = ()`
+    ([#3](https://github.com/haskell/deepseq/issues/3))
+
+  * Add `(<$!!>) :: (Monad m, NFData b) => (a -> b) -> m a -> m b`
+    ([#13](https://github.com/haskell/deepseq/issues/13))
+
+  * Add `NFData1` and `NFData2` type classes
+    ([#8](https://github.com/haskell/deepseq/issues/8))
+
+  * Add `NFData` instance for `Down` for `base` versions prior to
+    `base-4.6.0` which didn't yet export it via `Data.Ord`
+    ([#28](https://github.com/haskell/deepseq/pull/28))
+
+  * Add `NFData` instance for `Foreign.C.Types.CBool`
+    ([#33](https://github.com/haskell/deepseq/pull/33))
+
+  * Add `NFData` instance for `Ordering`
+    ([#25](https://github.com/haskell/deepseq/pull/25))
+
+  * Add `NFData1` and `NFData` instances for `Data.Functor.{Compose,Sum,Product}`
+    ([#30](https://github.com/haskell/deepseq/pull/30))
+
+  * Add `NFData`, `NFData1`, and `NFData2` instances for `(:~:)` and `(:~~:)`
+    from `Data.Type.Equality`
+    ([#31](https://github.com/haskell/deepseq/issues/31))
+
+## 1.4.2.0  *Apr 2016*
+
+  * Bundled with GHC 8.0.1
+
+  * New instances for types provided by `semigroups` prior to
+    `base-4.9` (i.e. `NonEmpty`, `Min`, `Max`, `Arg`,
+    `Semigroup.First`, `Semigroup.Last`, `WrappedMonoid`, and
+    `Option`) ([#11](https://github.com/haskell/deepseq/issues/11))
+
+  * New instances for `Ptr` and `FunPtr`
+    ([#10](https://github.com/haskell/deepseq/pull/10))
+
+  * New instances for `IORef`, `STRef`, and `MVar`
+    ([#6](https://github.com/haskell/deepseq/issues/6))
+
+  * New instance for `ExitCode`
+    ([#4](https://github.com/haskell/deepseq/issues/4))
+
+  * New instances for `CallStack` and `SrcLoc`
+
+  * Make `NFData (Proxy a)` instance poly-kinded
+
+## 1.4.1.2  *Aug 2015*
+
+  * Avoid the broken combination of GHC-7.2 with `array>=0.4`
+    ([#7](https://github.com/haskell/deepseq/pull/7))
+
+## 1.4.1.1  *Mar 2015*
+
+  * Bundled with GHC 7.10.1
+  * Drop redundant `ghc-prim` dependency
+
+## 1.4.1.0  *Mar 2015*
+
+  * Drop redundant constraints from a few `NFData` instances (if
+    possible for a given `base` version)
+
+## 1.4.0.0  *Dec 2014*
+
+  * Switch to Generics based `DefaultSignature` `rnf` method
+    implementation (based on code from `deepseq-generics`)
+
+    **Compatibility Note**: if you need the exact default-method
+    semantics of `deepseq` prior to 1.4, replace occurences of
+
+        instance NFData XYZ
+
+    by
+
+        instance NFData XYZ where rnf x = seq x ()
+
+  * New `NFData` instances for `base` types:
+
+     - `Control.Applicative.Const`
+     - `Control.Applicative.ZipList`
+     - `Control.Concurrent.ThreadId`
+     - `Data.Functor.Identity.Identity`
+     - `Data.Monoid.{Dual,First,Last,Any,All,Sum,Product}`
+     - `Data.Ord.Down`
+     - `Data.Proxy.Proxy`
+     - `Data.Typeable.Internal.TyCon`
+     - `Data.Typeable.Internal.TypeRep`
+     - `Data.Unique.Unique`
+     - `Data.Void.Void`
+     - `GHC.Fingerprint.Type.Fingerprint`
+     - `Numeric.Natural.Natural`
+     - `System.Mem.StableName.StableName`
+     - `Foreign.C.Types.C*`
+
+## 1.3.0.2  *Nov 2013*
+
+  * Bundled with GHC 7.8.1
+  * Update package description to Cabal 1.10 format
+  * Add support for GHC 7.8
+  * Drop support for GHCs older than GHC 7.0.1
+  * Add `/since: .../` annotations to Haddock comments
+  * Add changelog
+
+## 1.3.0.1  *Sep 2012*
+
+  * No changes
+
+## 1.3.0.0  *Feb 2012*
+
+  * Add instances for `Fixed`, `a->b` and `Version`
+
+## 1.2.0.1  *Sep 2011*
+
+  * Disable SafeHaskell for GHC 7.2
+
+## 1.2.0.0  *Sep 2011*
+
+  * New function `force`
+  * New operator `$!!`
+  * Add SafeHaskell support
+  * Dropped dependency on containers
+
+## 1.1.0.2  *Nov 2010*
+
+  * Improve Haddock documentation
+
+## 1.1.0.1  *Oct 2010*
+
+  * Enable support for containers-0.4.x
+
+## 1.1.0.0  *Nov 2009*
+
+  * Major rewrite
+
+## 1.0.0.0  *Nov 2009*
+
+  * Initial release
diff --git a/deepseq.cabal b/deepseq.cabal
--- a/deepseq.cabal
+++ b/deepseq.cabal
@@ -1,9 +1,13 @@
-name:		deepseq
-version:        1.3.0.1
-license:	BSD3
-license-file:	LICENSE
-maintainer:	libraries@haskell.org
-synopsis:	Deep evaluation of data structures
+cabal-version:  1.12
+name:           deepseq
+version:        1.6.0.0
+-- NOTE: Don't forget to update ./changelog.md
+
+license:        BSD3
+license-file:   LICENSE
+maintainer:     libraries@haskell.org
+bug-reports:    https://github.com/haskell/deepseq/issues
+synopsis:       Deep evaluation of data structures
 category:       Control
 description:
     This package provides methods for fully evaluating data structures
@@ -17,19 +21,68 @@
     \"deep\" version of 'seq'. It is implemented on top of an 'NFData'
     typeclass (\"Normal Form Data\", data structures with no unevaluated
     components) which defines strategies for fully evaluating different
-    data types.
-    .
+    data types. See module documentation in "Control.DeepSeq" for more
+    details.
+
 build-type:     Simple
-cabal-version:  >=1.6
+tested-with:
+  GHC==9.10.1,
+  GHC==9.8.2,
+  GHC==9.6.6,
+  GHC==9.4.8,
+  GHC==9.2.8,
+  GHC==9.0.2,
+  GHC==8.10.7,
+  GHC==8.8.4,
+  GHC==8.6.5
 
+extra-source-files: changelog.md
+
 source-repository head
-    type:     git
-    location: http://darcs.haskell.org/packages/deepseq.git/
+  type:     git
+  location: https://github.com/haskell/deepseq.git
 
-library {
+library
+  default-language: Haskell2010
+  other-extensions:
+    BangPatterns
+    CPP
+    DefaultSignatures
+    EmptyCase
+    FlexibleContexts
+    FlexibleInstances
+    GADTs
+    MultiParamTypeClasses
+    PolyKinds
+    Safe
+    TypeOperators
+
+  -- Solo lives in ghc-prim in GHC-9.0 (and maybe still in GHC-9.2)
+  if impl(ghc >=9.0)
+    build-depends: ghc-prim
+
+  build-depends: base       >= 4.12 && < 4.21
+  ghc-options: -Wall
+
   exposed-modules: Control.DeepSeq
-  build-depends: base       >= 3   && < 5, 
-                 array      >= 0.1 && < 0.5
+
+test-suite test
+  Default-Language: Haskell2010
+  hs-source-dirs: tests
+  main-is: Main.hs
+  type: exitcode-stdio-1.0
+  build-depends:
+    base,
+    deepseq,
+    ghc-prim
   ghc-options: -Wall
-  extensions: CPP
-}
+  other-extensions:
+    CPP
+    BangPatterns
+    DefaultSignatures
+    DeriveDataTypeable
+    DeriveGeneric
+    FlexibleContexts
+    Safe
+    TupleSections
+    TypeOperators
diff --git a/tests/Main.hs b/tests/Main.hs
new file mode 100644
--- /dev/null
+++ b/tests/Main.hs
@@ -0,0 +1,185 @@
+-- Code reused from http://hackage.haskell.org/package/deepseq-generics
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE TupleSections #-}
+
+module Main (main) where
+
+import Control.Concurrent.MVar
+-- IUT
+import Control.DeepSeq
+import Control.Exception
+import Control.Monad
+import Data.Bits
+import Data.IORef
+import Data.Typeable
+import Data.Word
+import GHC.Generics
+import System.Exit (exitFailure)
+import System.IO.Unsafe (unsafePerformIO)
+
+----------------------------------------------------------------------------
+-- simple hacky abstraction for testing forced evaluation via `rnf`-like functions
+
+seqStateLock :: MVar ()
+seqStateLock = unsafePerformIO $ newMVar ()
+{-# NOINLINE seqStateLock #-}
+
+withSeqState :: Word64 -> IO () -> IO ()
+withSeqState expectedState act = withMVar seqStateLock $ \() -> do
+  0 <- resetSeqState
+  () <- act
+  st <- resetSeqState
+  unless (st == expectedState) $ do
+    putStrLn $
+      "withSeqState: actual seq-state ("
+        ++ show st
+        ++ ") doesn't match expected value ("
+        ++ show expectedState
+        ++ ")"
+    exitFailure
+
+seqState :: IORef Word64
+seqState = unsafePerformIO $ newIORef 0
+{-# NOINLINE seqState #-}
+
+resetSeqState :: IO Word64
+resetSeqState = atomicModifyIORef' seqState (0,)
+
+-- | Set flag and raise exception is flag already set
+setSeqState :: Int -> IO ()
+setSeqState i
+  | 0 <= i && i < 64 = atomicModifyIORef' seqState go
+  | otherwise = error "seqSeqState: flag index must be in [0..63]"
+ where
+  go x
+    | testBit x i = error ("setSeqState: flag #" ++ show i ++ " already set")
+    | otherwise = (setBit x i, ())
+
+-- weird type whose NFData instance calls 'setSeqState' when rnf-ed
+data SeqSet = SeqSet !Int | SeqIgnore
+  deriving (Show)
+
+instance NFData SeqSet where
+  rnf (SeqSet i) = unsafePerformIO $ setSeqState i
+  rnf (SeqIgnore) = ()
+  {-# NOINLINE rnf #-}
+
+-- | Exception to be thrown for testing 'seq'/'rnf'
+data RnfEx = RnfEx deriving (Eq, Show, Typeable)
+
+instance Exception RnfEx
+
+instance NFData RnfEx where rnf e = throw e
+
+assertRnfEx :: () -> IO ()
+assertRnfEx v = handleJust isWanted (const $ return ()) $ do
+  () <- evaluate v
+  putStrLn "failed to trigger expected RnfEx exception"
+  exitFailure
+ where
+  isWanted = guard . (== RnfEx)
+
+----------------------------------------------------------------------------
+
+testCase :: String -> IO a -> IO a
+testCase testName io = do
+  putStrLn testName
+  io
+
+case_1, case_2, case_3 :: IO ()
+case_4_1, case_4_2, case_4_3, case_4_4 :: IO ()
+case_4_1b, case_4_2b, case_4_3b, case_4_4b :: IO ()
+
+newtype Case1 = Case1 Int
+  deriving (Generic)
+
+instance NFData Case1
+
+case_1 = testCase "Case1" $ do
+  assertRnfEx $ rnf $ (Case1 (throw RnfEx))
+
+----
+
+data Case2 = Case2 Int
+  deriving (Generic)
+
+instance NFData Case2
+
+case_2 = testCase "Case2" $ do
+  assertRnfEx $ rnf $ (Case2 (throw RnfEx))
+
+----
+
+data Case3 = Case3 RnfEx
+  deriving (Generic)
+
+instance NFData Case3
+
+case_3 = testCase "Case3" $ do
+  assertRnfEx $ rnf $ Case3 RnfEx
+
+----
+
+data Case4 a
+  = Case4a
+  | Case4b a a
+  | Case4c a (Case4 a)
+  deriving
+    ( Generic
+    , Generic1
+    )
+
+instance NFData a => NFData (Case4 a)
+
+instance NFData1 Case4
+
+case_4_1 = testCase "Case4.1" $ withSeqState 0x0 $ do
+  evaluate $ rnf $ (Case4a :: Case4 SeqSet)
+
+case_4_2 = testCase "Case4.2" $ withSeqState 0x3 $ do
+  evaluate $ rnf $ (Case4b (SeqSet 0) (SeqSet 1) :: Case4 SeqSet)
+
+case_4_3 = testCase "Case4.3" $ withSeqState (bit 55) $ do
+  evaluate $ rnf $ (Case4b SeqIgnore (SeqSet 55) :: Case4 SeqSet)
+
+case_4_4 = testCase "Case4.4" $ withSeqState 0xffffffffffffffff $ do
+  evaluate $ rnf $ (genCase 63)
+ where
+  genCase n
+    | n > 1 = Case4c (SeqSet n) (genCase (n - 1))
+    | otherwise = Case4b (SeqSet 0) (SeqSet 1)
+
+case_4_1b = testCase "Case4.1b" $ withSeqState 0x0 $ do
+  evaluate $ rnf1 $ (Case4a :: Case4 SeqSet)
+
+case_4_2b = testCase "Case4.2b" $ withSeqState 0x3 $ do
+  evaluate $ rnf1 $ (Case4b (SeqSet 0) (SeqSet 1) :: Case4 SeqSet)
+
+case_4_3b = testCase "Case4.3b" $ withSeqState (bit 55) $ do
+  evaluate $ rnf1 $ (Case4b SeqIgnore (SeqSet 55) :: Case4 SeqSet)
+
+case_4_4b = testCase "Case4.4b" $ withSeqState 0xffffffffffffffff $ do
+  evaluate $ rnf1 $ (genCase 63)
+ where
+  genCase n
+    | n > 1 = Case4c (SeqSet n) (genCase (n - 1))
+    | otherwise = Case4b (SeqSet 0) (SeqSet 1)
+
+----------------------------------------------------------------------------
+
+main :: IO ()
+main =
+  sequence_
+    [ case_1
+    , case_2
+    , case_3
+    , case_4_1
+    , case_4_2
+    , case_4_3
+    , case_4_4
+    , case_4_1b
+    , case_4_2b
+    , case_4_3b
+    , case_4_4b
+    ]
