|Version 9 (modified by dreixel, 11 months ago) (diff)|
The page describes an improved implementation of the Typeable class, using polymorphic kinds. Technically it is straightforward, but it represents a non-backward-compatible change to a widely used library, so we need to make a plan for the transition.
Open question: what are the corresponding changes to Data.Data? See #4896,
The current Typeable class
The current Typeable class is:
class Typeable (a :: *) where typeOf :: a -> TypeRep
Because it is mono-kinded we also have
class Typeable1 (f :: *->*) where typeOf1 :: f a -> TypeRep
and so on up to Typeable7. It's a mess, and we cannot make Typeable at all for type constructors with higher kinds like
Foo :: (* -> *) -> *
The new Typeable class
Having polymorphic kinds lets us say this:
data Proxy t = Proxy class Typeable t where typeRep :: proxy t -> TypeRep
- Typeable has a polymorphic kind:
Typeable :: forall k. k -> Constraint
- The method is called typeRep rather than typeOf
- One reason for the name change is that the argument is not a value of the type t, but a value of type (proxy t). We have to do this because t may have any kind, so we can't say
typeOf :: t -> TypeRep
- You can instantiate proxy to whatever you want; one common choice is the poly-kinded Proxy datatype:
Proxy:: forall k. k -> *
Now we can give give kind-specific instances:
instance Typeable Int where typeRep _ = ... instance Typeable  where typeRep _ = ... instance (Typeable a, Typeable b) => Typeable (a b) where typeRep _ = ...
A use of deriving( Typeable ) for a type constructor T would always generate
instance Typable T where typeRep _ = ....
i.e. an instance of T itself, not applied to anything.
class Typeable (a :: k) where typeRep :: TTypeRep a newtype TTypeRep a = TR TypeRep
Is this perhaps better?
A change-over plan
In GHC 7.8:
- Rename Data.Typeable to Data.OldTypeable and deprecate the whole module.
- Define a new library Data.Typeable with the new definitions in them.
- Include in Data.Typeable old methods for backward compatibility, but deprecate them:
typeOf :: forall a. Typeable a => a -> TypeRep typeOf _ = typeRep (Proxy :: Proxy a) typeOf1 :: forall t (a :: *). Typeable t => t a -> TypeRep typeOf1 _ = typeRep (Proxy :: Proxy t)
- Make deriving( Typeable ) work with whatever Typeable class is in scope. So what it does will be determined by whether you say import Data.Typeable or import Data.OldTypeable.
I think that means that old programs will continue to work in GHC 7.8, provided
- You did not mention Typeable1 etc explicitly
- You used deriving( Typeable ) to write instances.
In GHC 7.10:
- Remove Data.OldTypeable