Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

haskell

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?

like image 414
Mikhail Glushenkov Avatar asked Apr 24 '14 19:04

Mikhail Glushenkov


1 Answers

Well, ConstraintKinds 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.

like image 186
kosmikus Avatar answered Oct 10 '22 06:10

kosmikus