{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module NoThunks.Class (
NoThunks(..)
, ThunkInfo(..)
, Context
, unsafeNoThunks
, allNoThunks
, noThunksInValues
, noThunksInKeysAndValues
, OnlyCheckWhnf(..)
, OnlyCheckWhnfNamed(..)
, InspectHeap(..)
, InspectHeapNamed(..)
, AllowThunk(..)
, AllowThunksIn(..)
, GWNoThunks(..)
) where
import Data.Proxy
import Data.Typeable
import System.IO.Unsafe (unsafePerformIO)
import GHC.Exts.Heap
import GHC.Generics
import GHC.Records
import GHC.TypeLits
import GHC.Conc.Sync (ThreadId (..))
import Data.Foldable (toList)
import Data.Functor.Identity (Identity)
import Data.Int
import Data.IntMap (IntMap)
import Data.Kind (Type)
import Data.List.NonEmpty (NonEmpty (..))
import Data.Map (Map)
import Data.Ratio
import Data.Sequence (Seq)
import Data.Set (Set)
import Data.Time
import Data.Void (Void)
import Data.Word
import GHC.Stack
#if !MIN_VERSION_base(4,16,0)
import Numeric.Natural
#endif
import qualified Control.Concurrent.MVar as MVar
import qualified Control.Concurrent.STM.TVar as TVar
import qualified Data.IntMap as IntMap
import qualified Data.IORef as IORef
import qualified Data.Map as Map
import qualified Data.Set as Set
#ifdef MIN_VERSION_bytestring
import Data.ByteString.Short (ShortByteString)
import qualified Data.ByteString as BS.Strict
import qualified Data.ByteString.Lazy as BS.Lazy
import qualified Data.ByteString.Lazy.Internal as BS.Lazy.Internal
#endif
#ifdef MIN_VERSION_text
import qualified Data.Text as Text.Strict
import qualified Data.Text.Internal.Lazy as Text.Lazy.Internal
import qualified Data.Text.Lazy as Text.Lazy
#endif
#ifdef MIN_VERSION_vector
import qualified Data.Vector as Vector.Boxed
import qualified Data.Vector.Unboxed as Vector.Unboxed
#endif
class NoThunks a where
noThunks :: Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt a
x = do
Bool
isThunk <- forall a. a -> IO Bool
checkIsThunk a
x
if Bool
isThunk
then forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just ThunkInfo { thunkContext :: Context
thunkContext = Context
ctxt' }
else forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt' a
x
where
ctxt' :: Context
ctxt' :: Context
ctxt' = forall a. NoThunks a => Proxy a -> String
showTypeOf (forall {k} (t :: k). Proxy t
Proxy @a) forall a. a -> [a] -> [a]
: Context
ctxt
wNoThunks :: Context -> a -> IO (Maybe ThunkInfo)
default wNoThunks :: (Generic a, GWNoThunks '[] (Rep a))
=> Context -> a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt a
x = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks (forall {k} (t :: k). Proxy t
Proxy @'[]) Context
ctxt forall x. Rep a x
fp
where
fp :: Rep a x
!fp :: forall x. Rep a x
fp = forall a x. Generic a => a -> Rep a x
from a
x
showTypeOf :: Proxy a -> String
default showTypeOf :: (Generic a, GShowTypeOf (Rep a)) => Proxy a -> String
showTypeOf Proxy a
_ = forall (f :: * -> *) x. GShowTypeOf f => f x -> String
gShowTypeOf (forall a x. Generic a => a -> Rep a x
from a
x)
where
x :: a
x :: a
x = a
x
type Context = [String]
newtype ThunkInfo = ThunkInfo {
ThunkInfo -> Context
thunkContext :: Context
}
deriving (Int -> ThunkInfo -> ShowS
[ThunkInfo] -> ShowS
ThunkInfo -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ThunkInfo] -> ShowS
$cshowList :: [ThunkInfo] -> ShowS
show :: ThunkInfo -> String
$cshow :: ThunkInfo -> String
showsPrec :: Int -> ThunkInfo -> ShowS
$cshowsPrec :: Int -> ThunkInfo -> ShowS
Show)
{-# NOINLINE unsafeNoThunks #-}
unsafeNoThunks :: NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks :: forall a. NoThunks a => a -> Maybe ThunkInfo
unsafeNoThunks a
a = forall a. IO a -> a
unsafePerformIO forall a b. (a -> b) -> a -> b
$ forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks [] a
a
allNoThunks :: [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks :: [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks = [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
go
where
go :: [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
go :: [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
go [] = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
go (IO (Maybe ThunkInfo)
a:[IO (Maybe ThunkInfo)]
as) = do
Maybe ThunkInfo
nf <- IO (Maybe ThunkInfo)
a
case Maybe ThunkInfo
nf of
Maybe ThunkInfo
Nothing -> [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
go [IO (Maybe ThunkInfo)]
as
Just ThunkInfo
thunk -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just ThunkInfo
thunk
noThunksInValues :: NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues :: forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt = [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a -> b) -> [a] -> [b]
map (forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt)
noThunksInKeysAndValues :: (NoThunks k, NoThunks v)
=> Context -> [(k, v)] -> IO (Maybe ThunkInfo)
noThunksInKeysAndValues :: forall k v.
(NoThunks k, NoThunks v) =>
Context -> [(k, v)] -> IO (Maybe ThunkInfo)
noThunksInKeysAndValues Context
ctxt =
[IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks
forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(k
k, v
v) -> [ forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt k
k
, forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt v
v
])
newtype OnlyCheckWhnf a = OnlyCheckWhnf a
newtype OnlyCheckWhnfNamed (name :: Symbol) a = OnlyCheckWhnfNamed a
newtype AllowThunk a = AllowThunk a
newtype AllowThunksIn (fields :: [Symbol]) a = AllowThunksIn a
newtype InspectHeap a = InspectHeap a
newtype InspectHeapNamed (name :: Symbol) a = InspectHeapNamed a
instance Typeable a => NoThunks (OnlyCheckWhnf a) where
showTypeOf :: Proxy (OnlyCheckWhnf a) -> String
showTypeOf Proxy (OnlyCheckWhnf a)
_ = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall {k} (t :: k). Proxy t
Proxy @a)
wNoThunks :: Context -> OnlyCheckWhnf a -> IO (Maybe ThunkInfo)
wNoThunks Context
_ OnlyCheckWhnf a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
instance KnownSymbol name => NoThunks (OnlyCheckWhnfNamed name a) where
showTypeOf :: Proxy (OnlyCheckWhnfNamed name a) -> String
showTypeOf Proxy (OnlyCheckWhnfNamed name a)
_ = forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
Proxy @name)
wNoThunks :: Context -> OnlyCheckWhnfNamed name a -> IO (Maybe ThunkInfo)
wNoThunks Context
_ OnlyCheckWhnfNamed name a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
instance NoThunks (AllowThunk a) where
showTypeOf :: Proxy (AllowThunk a) -> String
showTypeOf Proxy (AllowThunk a)
_ = String
"<never used since never fails>"
noThunks :: Context -> AllowThunk a -> IO (Maybe ThunkInfo)
noThunks Context
_ AllowThunk a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
wNoThunks :: Context -> AllowThunk a -> IO (Maybe ThunkInfo)
wNoThunks = forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks
instance (HasFields s a, Generic a, Typeable a, GWNoThunks s (Rep a))
=> NoThunks (AllowThunksIn s a) where
showTypeOf :: Proxy (AllowThunksIn s a) -> String
showTypeOf Proxy (AllowThunksIn s a)
_ = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall {k} (t :: k). Proxy t
Proxy @a)
wNoThunks :: Context -> AllowThunksIn s a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt (AllowThunksIn a
x) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks (forall {k} (t :: k). Proxy t
Proxy @s) Context
ctxt forall x. Rep a x
fp
where
fp :: Rep a x
!fp :: forall x. Rep a x
fp = forall a x. Generic a => a -> Rep a x
from a
x
instance Typeable a => NoThunks (InspectHeap a) where
showTypeOf :: Proxy (InspectHeap a) -> String
showTypeOf Proxy (InspectHeap a)
_ = forall a. Show a => a -> String
show forall a b. (a -> b) -> a -> b
$ forall {k} (proxy :: k -> *) (a :: k).
Typeable a =>
proxy a -> TypeRep
typeRep (forall {k} (t :: k). Proxy t
Proxy @a)
wNoThunks :: Context -> InspectHeap a -> IO (Maybe ThunkInfo)
wNoThunks = forall a. Context -> a -> IO (Maybe ThunkInfo)
inspectHeap
instance KnownSymbol name => NoThunks (InspectHeapNamed name a) where
showTypeOf :: Proxy (InspectHeapNamed name a) -> String
showTypeOf Proxy (InspectHeapNamed name a)
_ = forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
Proxy @name)
wNoThunks :: Context -> InspectHeapNamed name a -> IO (Maybe ThunkInfo)
wNoThunks = forall a. Context -> a -> IO (Maybe ThunkInfo)
inspectHeap
inspectHeap :: Context -> a -> IO (Maybe ThunkInfo)
inspectHeap :: forall a. Context -> a -> IO (Maybe ThunkInfo)
inspectHeap Context
ctxt a
x = do
Bool
containsThunks <- forall a. a -> IO Bool
checkContainsThunks a
x
forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ if Bool
containsThunks
then forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ ThunkInfo { thunkContext :: Context
thunkContext = String
"..." forall a. a -> [a] -> [a]
: Context
ctxt }
else forall a. Maybe a
Nothing
class GWNoThunks (a :: [Symbol]) f where
gwNoThunks :: proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
instance GWNoThunks a f => GWNoThunks a (D1 c f) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> D1 c f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt (M1 f x
fp) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt f x
fp
instance GWNoThunks a f => GWNoThunks a (C1 c f) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> C1 c f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt (M1 f x
fp) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt f x
fp
instance GWNoThunks a f => GWNoThunks a (S1 ('MetaSel ('Nothing) su ss ds) f) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a
-> Context
-> S1 ('MetaSel 'Nothing su ss ds) f x
-> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt (M1 f x
fp) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt f x
fp
instance (GWNoThunks a f, GWNoThunks a g) => GWNoThunks a (f :*: g) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> (:*:) f g x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt (f x
fp :*: g x
gp) = [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks [
forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt f x
fp
, forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt g x
gp
]
instance (GWNoThunks a f, GWNoThunks a g) => GWNoThunks a (f :+: g) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> (:+:) f g x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt (L1 f x
fp) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt f x
fp
gwNoThunks proxy a
a Context
ctxt (R1 g x
gp) = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
a Context
ctxt g x
gp
instance NoThunks c => GWNoThunks a (K1 i c) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> K1 i c x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
_a Context
ctxt (K1 c
c) = forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt' c
c
where
ctxt' :: Context
ctxt' = case Context
ctxt of
String
hd : Context
tl | String
hd forall a. Eq a => a -> a -> Bool
== forall a. NoThunks a => Proxy a -> String
showTypeOf (forall {k} (t :: k). Proxy t
Proxy @c) -> Context
tl
Context
_otherwise -> Context
ctxt
instance GWNoThunks a U1 where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> U1 x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
_a Context
_ctxt U1 x
U1 = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
instance GWNoThunks a V1 where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a -> Context -> V1 x -> IO (Maybe ThunkInfo)
gwNoThunks proxy a
_a Context
_ctxt V1 x
_ = forall a. HasCallStack => String -> a
error String
"unreachable gwNoThunks @V1"
instance ( GWRecordField f (Elem fieldName a)
, KnownSymbol fieldName
)
=> GWNoThunks a (S1 ('MetaSel ('Just fieldName) su ss ds) f) where
gwNoThunks :: forall (proxy :: [Symbol] -> *) x.
proxy a
-> Context
-> S1 ('MetaSel ('Just fieldName) su ss ds) f x
-> IO (Maybe ThunkInfo)
gwNoThunks proxy a
_ Context
ctxt (M1 f x
fp) =
forall (f :: * -> *) (b :: Bool) (proxy :: Bool -> *) x.
GWRecordField f b =>
proxy b -> Context -> f x -> IO (Maybe ThunkInfo)
gwRecordField (forall {k} (t :: k). Proxy t
Proxy @(Elem fieldName a)) (forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal @fieldName forall {k} (t :: k). Proxy t
Proxy forall a. a -> [a] -> [a]
: Context
ctxt) f x
fp
class GWRecordField f (b :: Bool) where
gwRecordField :: proxy b -> Context -> f x -> IO (Maybe ThunkInfo)
instance GWRecordField f 'True where
gwRecordField :: forall (proxy :: Bool -> *) x.
proxy 'True -> Context -> f x -> IO (Maybe ThunkInfo)
gwRecordField proxy 'True
_ Context
_ f x
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
instance GWNoThunks '[] f => GWRecordField f 'False where
gwRecordField :: forall (proxy :: Bool -> *) x.
proxy 'False -> Context -> f x -> IO (Maybe ThunkInfo)
gwRecordField proxy 'False
_ Context
ctxt f x
f = forall (a :: [Symbol]) (f :: * -> *) (proxy :: [Symbol] -> *) x.
GWNoThunks a f =>
proxy a -> Context -> f x -> IO (Maybe ThunkInfo)
gwNoThunks (forall {k} (t :: k). Proxy t
Proxy @'[]) Context
ctxt f x
f
class GShowTypeOf f where
gShowTypeOf :: f x -> String
instance Datatype c => GShowTypeOf (D1 c f) where
gShowTypeOf :: forall x. D1 c f x -> String
gShowTypeOf = forall {k} (d :: k) k1 (t :: k -> (k1 -> *) -> k1 -> *)
(f :: k1 -> *) (a :: k1).
Datatype d =>
t d f a -> String
datatypeName
deriving via OnlyCheckWhnf Bool instance NoThunks Bool
deriving via OnlyCheckWhnf Natural instance NoThunks Natural
deriving via OnlyCheckWhnf Integer instance NoThunks Integer
deriving via OnlyCheckWhnf Float instance NoThunks Float
deriving via OnlyCheckWhnf Double instance NoThunks Double
deriving via OnlyCheckWhnf Char instance NoThunks Char
deriving via OnlyCheckWhnf Int instance NoThunks Int
deriving via OnlyCheckWhnf Int8 instance NoThunks Int8
deriving via OnlyCheckWhnf Int16 instance NoThunks Int16
deriving via OnlyCheckWhnf Int32 instance NoThunks Int32
deriving via OnlyCheckWhnf Int64 instance NoThunks Int64
deriving via OnlyCheckWhnf Word instance NoThunks Word
deriving via OnlyCheckWhnf Word8 instance NoThunks Word8
deriving via OnlyCheckWhnf Word16 instance NoThunks Word16
deriving via OnlyCheckWhnf Word32 instance NoThunks Word32
deriving via OnlyCheckWhnf Word64 instance NoThunks Word64
instance NoThunks a => NoThunks (IORef.IORef a) where
showTypeOf :: Proxy (IORef a) -> String
showTypeOf Proxy (IORef a)
_ = String
"IORef"
wNoThunks :: Context -> IORef a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctx IORef a
ref = do
a
val <- forall a. IORef a -> IO a
IORef.readIORef IORef a
ref
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx a
val
instance NoThunks a => NoThunks (MVar.MVar a) where
showTypeOf :: Proxy (MVar a) -> String
showTypeOf Proxy (MVar a)
_ = String
"MVar"
wNoThunks :: Context -> MVar a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctx MVar a
ref = do
Maybe a
val <- forall a. MVar a -> IO (Maybe a)
MVar.tryReadMVar MVar a
ref
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing) (forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx) Maybe a
val
instance NoThunks a => NoThunks (TVar.TVar a) where
showTypeOf :: Proxy (TVar a) -> String
showTypeOf Proxy (TVar a)
_ = String
"TVar"
wNoThunks :: Context -> TVar a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctx TVar a
ref = do
a
val <- forall a. TVar a -> IO a
TVar.readTVarIO TVar a
ref
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctx a
val
deriving via InspectHeap Day instance NoThunks Day
deriving via InspectHeap DiffTime instance NoThunks DiffTime
deriving via InspectHeap LocalTime instance NoThunks LocalTime
deriving via InspectHeap NominalDiffTime instance NoThunks NominalDiffTime
deriving via InspectHeap TimeLocale instance NoThunks TimeLocale
deriving via InspectHeap TimeOfDay instance NoThunks TimeOfDay
deriving via InspectHeap TimeZone instance NoThunks TimeZone
deriving via InspectHeap UniversalTime instance NoThunks UniversalTime
deriving via InspectHeap UTCTime instance NoThunks UTCTime
deriving via InspectHeap ZonedTime instance NoThunks ZonedTime
#ifdef MIN_VERSION_bytestring
deriving via OnlyCheckWhnfNamed "Strict.ByteString" BS.Strict.ByteString
instance NoThunks BS.Strict.ByteString
deriving via OnlyCheckWhnfNamed "ShortByteString" ShortByteString
instance NoThunks ShortByteString
instance NoThunks BS.Lazy.ByteString where
showTypeOf :: Proxy ByteString -> String
showTypeOf Proxy ByteString
_ = String
"Lazy.ByteString"
wNoThunks :: Context -> ByteString -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt ByteString
bs =
case ByteString
bs of
ByteString
BS.Lazy.Internal.Empty -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
BS.Lazy.Internal.Chunk ByteString
chunk ByteString
bs' -> [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks [
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt ByteString
chunk
, forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt ByteString
bs'
]
#endif
#ifdef MIN_VERSION_text
deriving via OnlyCheckWhnfNamed "Strict.Text" Text.Strict.Text
instance NoThunks Text.Strict.Text
instance NoThunks Text.Lazy.Text where
showTypeOf :: Proxy Text -> String
showTypeOf Proxy Text
_ = String
"Lazy.Text"
wNoThunks :: Context -> Text -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt Text
bs =
case Text
bs of
Text
Text.Lazy.Internal.Empty -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
Text.Lazy.Internal.Chunk Text
chunk Text
bs' -> [IO (Maybe ThunkInfo)] -> IO (Maybe ThunkInfo)
allNoThunks [
forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt Text
chunk
, forall a. NoThunks a => Context -> a -> IO (Maybe ThunkInfo)
noThunks Context
ctxt Text
bs'
]
#endif
instance ( NoThunks a
, NoThunks b
) => NoThunks (a, b)
instance ( NoThunks a
, NoThunks b
, NoThunks c
) => NoThunks (a, b, c)
instance ( NoThunks a
, NoThunks b
, NoThunks c
, NoThunks d
) => NoThunks (a, b, c, d)
instance ( NoThunks a
, NoThunks b
, NoThunks c
, NoThunks d
, NoThunks e
) => NoThunks (a, b, c, d, e)
instance ( NoThunks a
, NoThunks b
, NoThunks c
, NoThunks d
, NoThunks e
, NoThunks f
) => NoThunks (a, b, c, d, e, f)
instance ( NoThunks a
, NoThunks b
, NoThunks c
, NoThunks d
, NoThunks e
, NoThunks f
, NoThunks g
) => NoThunks (a, b, c, d, e, f, g)
instance NoThunks Void
instance NoThunks ()
instance NoThunks a => NoThunks [a]
instance NoThunks a => NoThunks (Identity a)
instance NoThunks a => NoThunks (Maybe a)
instance NoThunks a => NoThunks (NonEmpty a)
instance (NoThunks a, NoThunks b) => NoThunks (Either a b)
deriving via InspectHeap ThreadId instance NoThunks ThreadId
instance (NoThunks k, NoThunks v) => NoThunks (Map k v) where
showTypeOf :: Proxy (Map k v) -> String
showTypeOf Proxy (Map k v)
_ = String
"Map"
wNoThunks :: Context -> Map k v -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = forall k v.
(NoThunks k, NoThunks v) =>
Context -> [(k, v)] -> IO (Maybe ThunkInfo)
noThunksInKeysAndValues Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
instance NoThunks a => NoThunks (Set a) where
showTypeOf :: Proxy (Set a) -> String
showTypeOf Proxy (Set a)
_ = String
"Set"
wNoThunks :: Context -> Set a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Set a -> [a]
Set.toList
instance NoThunks a => NoThunks (IntMap a) where
showTypeOf :: Proxy (IntMap a) -> String
showTypeOf Proxy (IntMap a)
_ = String
"IntMap"
wNoThunks :: Context -> IntMap a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. IntMap a -> [(Int, a)]
IntMap.toList
#ifdef MIN_VERSION_vector
instance NoThunks a => NoThunks (Vector.Boxed.Vector a) where
showTypeOf :: Proxy (Vector a) -> String
showTypeOf Proxy (Vector a)
_ = String
"Boxed.Vector"
wNoThunks :: Context -> Vector a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Vector a -> [a]
Vector.Boxed.toList
instance NoThunks (Vector.Unboxed.Vector a) where
showTypeOf :: Proxy (Vector a) -> String
showTypeOf Proxy (Vector a)
_ = String
"Unboxed.Vector"
wNoThunks :: Context -> Vector a -> IO (Maybe ThunkInfo)
wNoThunks Context
_ Vector a
_ = forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
#endif
deriving via OnlyCheckWhnfNamed "->" (a -> b) instance NoThunks (a -> b)
deriving via OnlyCheckWhnfNamed "IO" (IO a) instance NoThunks (IO a)
deriving via AllowThunk CallStack instance NoThunks CallStack
instance NoThunks a => NoThunks (Seq a) where
showTypeOf :: Proxy (Seq a) -> String
showTypeOf Proxy (Seq a)
_ = String
"Seq"
wNoThunks :: Context -> Seq a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt = forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
instance NoThunks a => NoThunks (Ratio a) where
showTypeOf :: Proxy (Ratio a) -> String
showTypeOf Proxy (Ratio a)
_ = String
"Ratio"
wNoThunks :: Context -> Ratio a -> IO (Maybe ThunkInfo)
wNoThunks Context
ctxt Ratio a
r = forall a. NoThunks a => Context -> [a] -> IO (Maybe ThunkInfo)
noThunksInValues Context
ctxt [a
n, a
d]
where
!n :: a
n = forall a. Ratio a -> a
numerator Ratio a
r
!d :: a
d = forall a. Ratio a -> a
denominator Ratio a
r
type family Same s t where
Same s t = IsSame (CmpSymbol s t)
type family IsSame (o :: Ordering) where
IsSame 'EQ = 'True
IsSame _x = 'False
type family Or (a :: Bool) (b :: Bool) where
Or 'False 'False = 'False
Or _a _b = 'True
type family Elem (s :: Symbol) (xs :: [Symbol]) where
Elem s (x ': xs) = Or (Same s x) (Elem s xs)
Elem _s '[] = 'False
class HasFields (s :: [Symbol]) (a :: Type)
instance HasFields '[] a
instance (HasField x a t, HasFields xs a) => HasFields (x ': xs) a
checkIsThunk :: a -> IO Bool
checkIsThunk :: forall a. a -> IO Bool
checkIsThunk a
x = Closure -> Bool
closureIsThunk forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Box -> IO Closure
getBoxedClosureData (forall a. a -> Box
asBox a
x)
checkContainsThunks :: a -> IO Bool
checkContainsThunks :: forall a. a -> IO Bool
checkContainsThunks a
x = Box -> IO Bool
go (forall a. a -> Box
asBox a
x)
where
go :: Box -> IO Bool
go :: Box -> IO Bool
go Box
b = do
Closure
c <- Box -> IO Closure
getBoxedClosureData Box
b
if Closure -> Bool
closureIsThunk Closure
c then
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
else do
Closure
c' <- Box -> IO Closure
getBoxedClosureData Box
b
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM Box -> IO Bool
go (forall b. GenClosure b -> [b]
allClosures Closure
c')
closureIsThunk :: Closure -> Bool
closureIsThunk :: Closure -> Bool
closureIsThunk ThunkClosure{} = Bool
True
closureIsThunk APClosure{} = Bool
True
closureIsThunk SelectorClosure{} = Bool
True
closureIsThunk BCOClosure{} = Bool
True
closureIsThunk Closure
_ = Bool
False
anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
anyM :: forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM a -> m Bool
_ [] = forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
anyM a -> m Bool
p (a
x : [a]
xs) = do
Bool
q <- a -> m Bool
p a
x
if Bool
q then forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True
else forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM a -> m Bool
p [a]
xs