{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ >= 702
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
# if MIN_VERSION_array(0,4,0)
{-# LANGUAGE Safe #-}
# endif
#endif
#if __GLASGOW_HASKELL__ >= 706
{-# LANGUAGE PolyKinds #-}
#endif
module Control.DeepSeq (
deepseq, ($!!), force,
NFData(..),
) 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) )
#endif
#if MIN_VERSION_base(4,7,0)
import Data.Proxy ( Proxy(Proxy) )
#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(..) )
#elif MIN_VERSION_base(4,8,1)
import GHC.Stack ( CallStack(..) )
import GHC.SrcLoc ( SrcLoc(..) )
#endif
#if __GLASGOW_HASKELL__ >= 702
import GHC.Fingerprint.Type ( Fingerprint(..) )
import GHC.Generics
class GNFData f where
grnf :: f a -> ()
instance GNFData V1 where
grnf = error "Control.DeepSeq.rnf: uninhabited type"
instance GNFData U1 where
grnf U1 = ()
instance NFData a => GNFData (K1 i a) where
grnf = rnf . unK1
{-# INLINEABLE grnf #-}
instance GNFData a => GNFData (M1 i c a) where
grnf = grnf . unM1
{-# INLINEABLE grnf #-}
instance (GNFData a, GNFData b) => GNFData (a :*: b) where
grnf (x :*: y) = grnf x `seq` grnf y
{-# INLINEABLE grnf #-}
instance (GNFData a, GNFData b) => GNFData (a :+: b) where
grnf (L1 x) = grnf x
grnf (R1 x) = grnf x
{-# INLINEABLE grnf #-}
#endif
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
class NFData a where
rnf :: a -> ()
#if __GLASGOW_HASKELL__ >= 702
default rnf :: (Generic a, GNFData (Rep a)) => a -> ()
rnf = grnf . from
#endif
instance NFData Int where rnf !_ = ()
instance NFData Word where rnf !_ = ()
instance NFData Integer where rnf !_ = ()
instance NFData Float where rnf !_ = ()
instance NFData Double where rnf !_ = ()
instance NFData Char where rnf !_ = ()
instance NFData Bool where rnf !_ = ()
instance NFData () where rnf !_ = ()
instance NFData Int8 where rnf !_ = ()
instance NFData Int16 where rnf !_ = ()
instance NFData Int32 where rnf !_ = ()
instance NFData Int64 where rnf !_ = ()
instance NFData Word8 where rnf !_ = ()
instance NFData Word16 where rnf !_ = ()
instance NFData Word32 where rnf !_ = ()
instance NFData Word64 where rnf !_ = ()
#if MIN_VERSION_base(4,7,0)
instance NFData (Proxy a) where rnf Proxy = ()
#endif
#if MIN_VERSION_base(4,8,0)
instance NFData a => NFData (Identity a) where
rnf = rnf . runIdentity
instance NFData Void where
rnf = absurd
instance NFData Natural where rnf !_ = ()
#endif
instance NFData (Fixed a) where rnf !_ = ()
instance NFData (a -> b) where rnf !_ = ()
#if __GLASGOW_HASKELL__ >= 711
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)
#if MIN_VERSION_base(4,4,0)
instance (NFData a) => NFData (Complex a) where
#else
instance (RealFloat a, NFData a) => NFData (Complex a) where
#endif
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 NFData a => NFData (ZipList a) where
rnf = rnf . getZipList
instance NFData a => NFData (Const a b) where
rnf = rnf . 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 MIN_VERSION_base(4,6,0)
instance NFData a => NFData (Down a) where
rnf (Down x) = rnf x
#endif
instance NFData a => NFData (Dual a) where
rnf = rnf . getDual
instance NFData a => NFData (Mon.First a) where
rnf = rnf . Mon.getFirst
instance NFData a => NFData (Mon.Last a) where
rnf = rnf . Mon.getLast
instance NFData Any where rnf = rnf . getAny
instance NFData All where rnf = rnf . getAll
instance NFData a => NFData (Sum a) where
rnf = rnf . getSum
instance NFData a => NFData (Product a) where
rnf = rnf . getProduct
instance NFData (StableName a) where
rnf !_ = ()
instance NFData ThreadId where
rnf !_ = ()
instance NFData Unique where
rnf !_ = ()
#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 !_ = ()
instance NFData (STRef s a) where
rnf !_ = ()
instance NFData (MVar a) where
rnf !_ = ()
#if __GLASGOW_HASKELL__ >= 702
instance NFData Fingerprint where
rnf (Fingerprint _ _) = ()
#endif
instance NFData (Ptr a) where rnf !_ = ()
instance NFData (FunPtr a) where rnf !_ = ()
instance NFData CChar where rnf !_ = ()
instance NFData CSChar where rnf !_ = ()
instance NFData CUChar where rnf !_ = ()
instance NFData CShort where rnf !_ = ()
instance NFData CUShort where rnf !_ = ()
instance NFData CInt where rnf !_ = ()
instance NFData CUInt where rnf !_ = ()
instance NFData CLong where rnf !_ = ()
instance NFData CULong where rnf !_ = ()
instance NFData CPtrdiff where rnf !_ = ()
instance NFData CSize where rnf !_ = ()
instance NFData CWchar where rnf !_ = ()
instance NFData CSigAtomic where rnf !_ = ()
instance NFData CLLong where rnf !_ = ()
instance NFData CULLong where rnf !_ = ()
instance NFData CIntPtr where rnf !_ = ()
instance NFData CUIntPtr where rnf !_ = ()
instance NFData CIntMax where rnf !_ = ()
instance NFData CUIntMax where rnf !_ = ()
instance NFData CClock where rnf !_ = ()
instance NFData CTime where rnf !_ = ()
#if MIN_VERSION_base(4,4,0)
instance NFData CUSeconds where rnf !_ = ()
instance NFData CSUSeconds where rnf !_ = ()
#endif
instance NFData CFloat where rnf !_ = ()
instance NFData CDouble where rnf !_ = ()
instance NFData CFile where rnf !_ = ()
instance NFData CFpos where rnf !_ = ()
instance NFData CJmpBuf where rnf !_ = ()
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 (x :| xs) = rnf x `seq` rnf xs
instance NFData a => NFData (Min a) where
rnf (Min a) = rnf a
instance NFData a => NFData (Max a) where
rnf (Max a) = rnf a
instance (NFData a, NFData b) => NFData (Arg a b) where
rnf (Arg a b) = rnf a `seq` rnf b `seq` ()
instance NFData a => NFData (Semi.First a) where
rnf (Semi.First a) = rnf a
instance NFData a => NFData (Semi.Last a) where
rnf (Semi.Last a) = rnf a
instance NFData m => NFData (WrappedMonoid m) where
rnf (WrapMonoid a) = rnf a
instance NFData a => NFData (Option a) where
rnf (Option a) = rnf 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 (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