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:
-
trTyConFingerprintis simply a fold over a known list -
trTyConis theTyConitself -
trKindVarsis simply the given list of kind variables -
trTyConKindis a bit tricky as it instantiates the tycon'sKindRep. However, in the case of a kind-monomorphic type this instantiation is trivial.
Edited by Ben Gamari