    {-# LANGUAGE CPP                      #-}
    {-# LANGUAGE GADTs                    #-}
    {-# LANGUAGE PolyKinds                #-}
    {-# LANGUAGE Safe                     #-}
    {-# LANGUAGE TypeOperators            #-}
    #if __GLASGOW_HASKELL__ >= 810
    {-# LANGUAGE StandaloneKindSignatures #-}
    #endif
    module Data.GADT.DeepSeq (
        GNFData (..),
        ) where

    import Data.Functor.Product (Product (..))
    import Data.Functor.Sum     (Sum (..))
    import Data.Type.Equality   ((:~:) (..), (:~~:) (..))
    import GHC.Generics         ((:*:) (..), (:+:) (..))

    import qualified Type.Reflection as TR

    #if __GLASGOW_HASKELL__ >= 810
    import Data.Kind (Constraint, Type)
    #endif

    #if __GLASGOW_HASKELL__ >= 810
    type GNFData :: (k -> Type) -> Constraint
    #endif

    class GNFData f where
        grnf :: f a -> ()

    instance (GNFData a, GNFData b) => GNFData (Product a b) where
        grnf :: forall (a :: k). Product a b a -> ()
    grnf (Pair a a
    a b a
    b) = a a -> ()
    forall (a :: k). a a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf a a
    a () -> () -> ()
    forall a b. a -> b -> b
    `seq` b a -> ()
    forall (a :: k). b a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf b a
    b

    instance (GNFData a, GNFData b) => GNFData (Sum a b) where
        grnf :: forall (a :: k). Sum a b a -> ()
    grnf (InL a a
    x) = a a -> ()
    forall (a :: k). a a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf a a
    x
        grnf (InR b a
    y) = b a -> ()
    forall (a :: k). b a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf b a
    y

    instance (GNFData a, GNFData b) => GNFData (a :*: b) where
        grnf :: forall (a :: k). (:*:) a b a -> ()
    grnf (a a
    a :*: b a
    b) = a a -> ()
    forall (a :: k). a a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf a a
    a () -> () -> ()
    forall a b. a -> b -> b
    `seq` b a -> ()
    forall (a :: k). b a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf b a
    b

    instance (GNFData a, GNFData b) => GNFData (a :+: b) where
        grnf :: forall (a :: k). (:+:) a b a -> ()
    grnf (L1 a a
    x) = a a -> ()
    forall (a :: k). a a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf a a
    x
        grnf (R1 b a
    y) = b a -> ()
    forall (a :: k). b a -> ()
    forall k (f :: k -> *) (a :: k). GNFData f => f a -> ()
    grnf b a
    y

    -- | @since 1.0.3
    instance GNFData ((:~:) a) where
        grnf :: forall (a :: k). (a :~: a) -> ()
    grnf a :~: a
    Refl = ()

    -- | @since 1.0.4
    instance GNFData ((:~~:) a) where
        grnf :: forall (a :: k). (a :~~: a) -> ()
    grnf a :~~: a
    HRefl = ()

    -- | @since 1.0.3
    instance GNFData TR.TypeRep where
        grnf :: forall (a :: k). TypeRep a -> ()
    grnf = TypeRep a -> ()
    forall k (a :: k). TypeRep a -> ()
    TR.rnfTypeRep