Typeable evidence is always CAFfy
It turns out that Typeable
's TypeRep
evidence, which ends up being quite widely used in the exception machinery and elsewhere, produces gobs of CAFs. For instance, consider the case of typeRep @Int
. Today this will result in the evidence binding:
tr :: TypeRep Int
tr = Data.Typeable.Internal.mkTrCon $tcInt []
After being floated to the top-level (as it very likely will be) this binding is, of course, a CAF. However, on examining the definition of mkTrCon
one might suspect that this could be easily reduced to a static constructor application:
mkTrCon :: forall k (a :: k). TyCon -> [SomeTypeRep] -> TypeRep a
mkTrCon tc kind_vars
= TrTyCon
{ trTyConFingerprint = fpr
, trTyCon = tc
, trKindVars = kind_vars
, trTyConKind = kind }
where
fpr_tc = tyConFingerprint tc
fpr_kvs = map someTypeRepFingerprint kind_vars
fpr = fingerprintFingerprints (fpr_tc:fpr_kvs)
kind = unsafeCoerceRep $ tyConKind tc kind_vars
Nearly all of this computation can, in principle, be done at compile-time:
-
trTyConFingerprint
is simply a fold over a known list -
trTyCon
is theTyCon
itself -
trKindVars
is simply the given list of kind variables -
trTyConKind
is a bit tricky as it instantiates the tycon'sKindRep
. However, in the case of a kind-monomorphic type this instantiation is trivial.