{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TypeOperators #-}
#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds #-}
#endif
#if __GLASGOW_HASKELL__ >= 708
{-# LANGUAGE EmptyCase #-}
#endif
module Control.DeepSeq (
     
     NFData(rnf),
     
     deepseq,
     force,
     ($!!),
     (<$!!>),
     rwhnf,
     
     
     NFData1(liftRnf), rnf1,
     
     NFData2(liftRnf2), rnf2,
  ) where
import Control.Applicative
import Control.Concurrent ( ThreadId, MVar )
import Data.IORef
import Data.STRef
import Data.Int
import Data.Word
import Data.Ratio
import Data.Complex
import Data.Array
import Data.Fixed
import Data.Version
import Data.Monoid as Mon
import Data.Unique ( Unique )
import Foreign.Ptr
import Foreign.C.Types
import System.Exit ( ExitCode(..) )
import System.Mem.StableName ( StableName )
#if MIN_VERSION_base(4,6,0)
import Data.Ord ( Down(Down) )
#else
import Control.DeepSeq.BackDoor ( Down(Down) )
#endif
#if MIN_VERSION_base(4,7,0)
import Data.Proxy ( Proxy(Proxy) )
#endif
#if MIN_VERSION_base(4,10,0)
import Data.Type.Equality ( (:~:), (:~~:) )
#elif MIN_VERSION_base(4,9,0)
import Data.Type.Equality ( (:~:) )
#elif MIN_VERSION_base(4,7,0)
import Control.DeepSeq.BackDoor ( (:~:) )
#endif
#if MIN_VERSION_base(4,8,0)
import Data.Functor.Identity ( Identity(..) )
import Data.Typeable ( TypeRep, TyCon, rnfTypeRep, rnfTyCon )
import Data.Void ( Void, absurd )
import Numeric.Natural ( Natural )
#endif
#if MIN_VERSION_base(4,9,0)
import Data.List.NonEmpty ( NonEmpty (..) )
import Data.Semigroup as Semi
#endif
#if MIN_VERSION_base(4,9,0)
import GHC.Stack.Types ( CallStack(..), SrcLoc(..) )
import Data.Functor.Compose
import qualified Data.Functor.Sum as Functor
import qualified Data.Functor.Product as Functor
#elif MIN_VERSION_base(4,8,1)
import GHC.Stack ( CallStack(..) )
import GHC.SrcLoc ( SrcLoc(..) )
#endif
import GHC.Fingerprint.Type ( Fingerprint(..) )
import GHC.Generics
class GNFData arity f where
  grnf :: RnfArgs arity a -> f a -> ()
instance GNFData arity V1 where
#if __GLASGOW_HASKELL__ >= 708
  grnf _ x = case x of {}
#else
  grnf _ !_ = error "Control.DeepSeq.rnf: uninhabited type"
#endif
data Zero
data One
data RnfArgs arity a where
  RnfArgs0 :: RnfArgs Zero a
  RnfArgs1  :: (a -> ()) -> RnfArgs One 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 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 $!!
deepseq :: NFData a => a -> b -> b
deepseq a b = rnf a `seq` b
($!!) :: (NFData a) => (a -> b) -> a -> b
f $!! x = x `deepseq` f x
force :: (NFData a) => a -> a
force x = x `deepseq` x
(<$!!>) :: (Monad m, NFData b) => (a -> b) -> m a -> m b
#if MIN_VERSION_base(4,8,0)
f <$!!> m = m >>= \x -> pure $!! f x
#else
f <$!!> m = m >>= \x -> return $!! f x
#endif
infixl 4 <$!!>
rwhnf :: a -> ()
rwhnf = (`seq` ())
{-# INLINE rwhnf #-}
class NFData a where
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    rnf :: a -> ()
    default rnf :: (Generic a, GNFData Zero (Rep a)) => a -> ()
    rnf = grnf RnfArgs0 . from
class NFData1 f where
    
    
    
    
    
    liftRnf :: (a -> ()) -> f a -> ()
    default liftRnf :: (Generic1 f, GNFData One (Rep1 f)) => (a -> ()) -> f a -> ()
    liftRnf r = grnf (RnfArgs1 r) . from1
rnf1 :: (NFData1 f, NFData a) => f a -> ()
rnf1 = liftRnf rnf
class NFData2 p where
    
    
    
    
    
    
    liftRnf2 :: (a -> ()) -> (b -> ()) -> p a b -> ()
rnf2 :: (NFData2 p, NFData a, NFData b) => p a b -> ()
rnf2 = liftRnf2 rnf rnf
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
#if MIN_VERSION_base(4,7,0)
instance NFData (Proxy a) where rnf Proxy = ()
instance NFData1 Proxy    where liftRnf _ Proxy = ()
instance NFData (a :~: b) where rnf = rwhnf
instance NFData1 ((:~:) a) where liftRnf _ = rwhnf
instance NFData2 (:~:) where liftRnf2 _ _ = rwhnf
#endif
#if MIN_VERSION_base(4,10,0)
instance NFData (a :~~: b) where rnf = rwhnf
instance NFData1 ((:~~:) a) where liftRnf _ = rwhnf
instance NFData2 (:~~:) where liftRnf2 _ _ = rwhnf
#endif
#if MIN_VERSION_base(4,8,0)
instance NFData a => NFData (Identity a) where
    rnf = rnf1
instance NFData1 Identity where
    liftRnf r = r . runIdentity
instance NFData Void where
    rnf = absurd
instance NFData Natural  where rnf = rwhnf
#endif
instance NFData (Fixed a) where rnf = rwhnf
instance NFData1 Fixed where liftRnf _ = rwhnf
instance NFData (a -> b) where rnf = rwhnf
#if MIN_VERSION_base(4,9,0)
instance NFData1 Ratio where
  liftRnf r x = r (numerator x) `seq` r (denominator x)
instance (NFData1 f, NFData1 g) => NFData1 (Compose f g) where
  liftRnf r = liftRnf (liftRnf r) . getCompose
instance (NFData1 f, NFData1 g, NFData a) => NFData (Compose f g a) where
  rnf = rnf1
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
instance (NFData1 f, NFData1 g, NFData a) => NFData (Functor.Sum f g a) where
  rnf = rnf1
instance (NFData1 f, NFData1 g) => NFData1 (Functor.Product f g) where
  liftRnf rnf0 (Functor.Pair f g) = liftRnf rnf0 f `seq` liftRnf rnf0 g
instance (NFData1 f, NFData1 g, NFData a) => NFData (Functor.Product f g a) where
  rnf = rnf1
instance NFData a => NFData (Ratio a) where
#else
instance (Integral a, NFData a) => NFData (Ratio a) where
#endif
  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
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
instance (NFData a) => NFData1 (Either a) where liftRnf = liftRnf2 rnf
instance NFData2 Either where
    liftRnf2  l _r (Left x)  = l x
    liftRnf2 _l  r (Right y) = r 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 = rnf1
instance NFData1 [] where
    liftRnf r = go
      where
        go [] = ()
        go (x:xs) = r x `seq` go xs
instance NFData a => NFData (ZipList a) where rnf = rnf1
instance NFData1 ZipList where
    liftRnf r = liftRnf r . getZipList
instance NFData a => NFData (Const a b) where
    rnf = rnf . getConst
instance NFData a => NFData1 (Const a) where
    liftRnf _ = rnf . getConst
instance NFData2 Const where
    liftRnf2 r _ = r . getConst
#if __GLASGOW_HASKELL__ >= 711
instance (NFData a, NFData b) => NFData (Array a b) where
#else
instance (Ix a, NFData a, NFData b) => NFData (Array a b) where
#endif
    rnf x = rnf (bounds x, Data.Array.elems x)
#if __GLASGOW_HASKELL__ >= 711
instance (NFData a) => NFData1 (Array a) where
#else
instance (Ix a, NFData a) => NFData1 (Array a) where
#endif
    liftRnf r x = rnf (bounds x) `seq` liftRnf r (Data.Array.elems x)
#if __GLASGOW_HASKELL__ >= 711
instance NFData2 Array where
    liftRnf2 r r' x = liftRnf2 r r (bounds x) `seq` liftRnf r' (Data.Array.elems x)
#endif
instance NFData a => NFData (Down a) where rnf = rnf1
instance NFData1 Down where
    liftRnf r (Down x) = r x
instance NFData a => NFData (Dual a) where rnf = rnf1
instance NFData1 Dual where
    liftRnf r (Dual x) = r x
instance NFData a => NFData (Mon.First a) where rnf = rnf1
instance NFData1 Mon.First  where
    liftRnf r (Mon.First x) = liftRnf r x
instance NFData a => NFData (Mon.Last a) where rnf = rnf1
instance NFData1 Mon.Last  where
    liftRnf r (Mon.Last  x) = liftRnf r x
instance NFData Any where rnf = rnf . getAny
instance NFData All where rnf = rnf . getAll
instance NFData a => NFData (Sum a) where rnf = rnf1
instance NFData1 Sum where
    liftRnf r (Sum x) = r x
instance NFData a => NFData (Product a) where rnf = rnf1
instance NFData1 Product where
    liftRnf r (Product x) = r x
instance NFData (StableName a) where
    rnf = rwhnf 
instance NFData1 StableName where
    liftRnf _ = rwhnf
instance NFData ThreadId where
    rnf = rwhnf 
instance NFData Unique where
    rnf = rwhnf 
#if MIN_VERSION_base(4,8,0)
instance NFData TypeRep where
    rnf tyrep = rnfTypeRep tyrep
instance NFData TyCon where
    rnf tycon = rnfTyCon tycon
#endif
instance NFData (IORef a) where
    rnf = rwhnf
instance NFData1 IORef where
    liftRnf _ = rwhnf
instance NFData (STRef s a) where
    rnf = rwhnf
instance NFData1 (STRef s) where
    liftRnf _ = rwhnf
instance NFData2 STRef where
    liftRnf2 _ _ = rwhnf
instance NFData (MVar a) where
  rnf = rwhnf
instance NFData1 MVar where
    liftRnf _ = rwhnf
instance NFData Fingerprint where
    rnf (Fingerprint _ _) = ()
instance NFData (Ptr a) where
    rnf = rwhnf
instance NFData1 Ptr where
    liftRnf _ = rwhnf
instance NFData (FunPtr a) where
    rnf = rwhnf
instance NFData1 FunPtr where
    liftRnf _ = rwhnf
instance NFData CChar where rnf = rwhnf
instance NFData CSChar where rnf = rwhnf
instance NFData CUChar where rnf = rwhnf
instance NFData CShort where rnf = rwhnf
instance NFData CUShort where rnf = rwhnf
instance NFData CInt where rnf = rwhnf
instance NFData CUInt where rnf = rwhnf
instance NFData CLong where rnf = rwhnf
instance NFData CULong where rnf = rwhnf
instance NFData CPtrdiff where rnf = rwhnf
instance NFData CSize where rnf = rwhnf
instance NFData CWchar where rnf = rwhnf
instance NFData CSigAtomic where rnf = rwhnf
instance NFData CLLong where rnf = rwhnf
instance NFData CULLong where rnf = rwhnf
instance NFData CIntPtr where rnf = rwhnf
instance NFData CUIntPtr where rnf = rwhnf
instance NFData CIntMax where rnf = rwhnf
instance NFData CUIntMax where rnf = rwhnf
instance NFData CClock where rnf = rwhnf
instance NFData CTime where rnf = rwhnf
instance NFData CUSeconds where rnf = rwhnf
instance NFData CSUSeconds where rnf = rwhnf
instance NFData CFloat where rnf = rwhnf
instance NFData CDouble where rnf = rwhnf
instance NFData CFile where rnf = rwhnf
instance NFData CFpos where rnf = rwhnf
instance NFData CJmpBuf where rnf = rwhnf
#if MIN_VERSION_base(4,10,0)
instance NFData CBool where rnf = rwhnf
#endif
instance NFData ExitCode where
  rnf (ExitFailure n) = rnf n
  rnf ExitSuccess     = ()
#if MIN_VERSION_base(4,9,0)
instance NFData a => NFData (NonEmpty a) where rnf = rnf1
instance NFData1 NonEmpty where
  liftRnf r (x :| xs) = r x `seq` liftRnf r xs
instance NFData a => NFData (Min a) where rnf = rnf1
instance NFData1 Min where
  liftRnf r (Min a) = r a
instance NFData a => NFData (Max a) where rnf = rnf1
instance NFData1 Max where
  liftRnf r (Max a) = r a
instance (NFData a, NFData b) => NFData (Arg a b) where rnf = rnf2
instance (NFData a) => NFData1 (Arg a) where liftRnf = liftRnf2 rnf
instance NFData2 Arg where
  liftRnf2 r r' (Arg a b) = r a `seq` r' b `seq` ()
instance NFData a => NFData (Semi.First a) where rnf = rnf1
instance NFData1 Semi.First where
  liftRnf r (Semi.First a) = r a
instance NFData a => NFData (Semi.Last a) where rnf = rnf1
instance NFData1 Semi.Last where
  liftRnf r (Semi.Last a) = r a
instance NFData m => NFData (WrappedMonoid m) where rnf = rnf1
instance NFData1 WrappedMonoid where
  liftRnf r (WrapMonoid a) = r a
instance NFData a => NFData (Option a) where rnf = rnf1
instance NFData1 Option where
  liftRnf r (Option a) = liftRnf r a
#endif
#if MIN_VERSION_base(4,9,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
instance NFData CallStack where
  rnf EmptyCallStack = ()
  rnf (PushCallStack a b c) = rnf a `seq` rnf b `seq` rnf c
  rnf (FreezeCallStack a)   = rnf a
#elif MIN_VERSION_base(4,8,1)
instance NFData SrcLoc where
  
  rnf sl = rnf (srcLocPackage   sl) `seq`
           rnf (srcLocModule    sl) `seq`
           rnf (srcLocFile      sl) `seq`
           rnf (srcLocStartLine sl) `seq`
           rnf (srcLocStartCol  sl) `seq`
           rnf (srcLocEndLine   sl) `seq`
           rnf (srcLocEndCol    sl)
instance NFData CallStack where
  rnf = rnf . getCallStack
#endif
instance (NFData a, NFData b) => NFData (a,b) where rnf = rnf2
instance (NFData a) => NFData1 ((,) a) where liftRnf = liftRnf2 rnf
instance NFData2 (,) where
  liftRnf2 r r' (x,y) = r x `seq` r' y
instance (NFData a1, NFData a2, NFData a3) =>
         NFData (a1, a2, a3) where rnf = rnf2
instance (NFData a1, NFData a2) =>
         NFData1 ((,,) a1 a2) where liftRnf = liftRnf2 rnf
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
instance (NFData a1, NFData a2, NFData a3) =>
         NFData1 ((,,,) a1 a2 a3) where liftRnf = liftRnf2 rnf
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
instance (NFData a1, NFData a2, NFData a3, NFData a4) =>
         NFData1 ((,,,,) a1 a2 a3 a4) where liftRnf = liftRnf2 rnf
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
instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5) =>
         NFData1 ((,,,,,) a1 a2 a3 a4 a5) where liftRnf = liftRnf2 rnf
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
instance (NFData a1, NFData a2, NFData a3, NFData a4, NFData a5, NFData a6) =>
         NFData1 ((,,,,,,) a1 a2 a3 a4 a5 a6) where liftRnf = liftRnf2 rnf
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
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
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
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
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