简体   繁体   中英

What is the purpose of the `Typeable (* -> Constraint) Monoid` instance?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM