Since GHC 7.8, Typeable
is poly-kinded. Looking at the list of built-in Typeable
instances in the documentation, I noticed something interesting:
Typeable ((* -> *) -> Constraint) Alternative
Typeable ((* -> *) -> Constraint) Applicative
Typeable (* -> Constraint) Monoid
Apparently, it's allowed to look at type representations of (certain) types of kind Constraint
:
Prelude Data.Monoid Data.Typeable> typeRep $ (Proxy :: Proxy (Monoid Int))
Monoid Int
Are there any uses for this feature or was it just made available by accident?
Well, ConstraintKind
s are now allowed. So this means that you can define datatypes parameterized over constraints.
A (contrived) example:
data CPair (c :: * -> Constraint) where
MkCPair :: (c a, c b) => a -> b -> CPair c
This is a pair of two components of potentially different types that share a common class:
aPair :: CPair Show
aPair = MkCPair 'x' True
Now, do we want aPair
to be Typeable
? This requires both CPair
and Show
to
be Typeable
as well.
deriving instance Typeable CPair
deriving instance Typeable Show
Now:
GHCi> typeOf aPair
CPair Show
So it's only consequent to derive Typeable
for classes if they can appear as types now.
The funny thing is that Typeable Show
isn't predefined, but Typeable Applicative
is. This is because there's a new GHC extension AutoDeriveTypeable
which seems to be enabled in some modules, but not in others. With AutoDeriveTypeable
, there are Typeable
instances being derived for everything in a module, including classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With