Changes to Data.Typeable

Simon Marlow marlowsd at
Thu Jul 7 21:00:53 CEST 2011

On 07/07/11 17:14, Gábor Lehel wrote:
> On Thu, Jul 7, 2011 at 5:44 PM, Simon Marlow<marlowsd at>  wrote:
>> Hi folks,
>> In response to this ticket:
>> I'm making some changes to Data.Typeable, some of which affect the API, so
>> as per the new library guidelines I'm informing the list.
>> The current implementation of Typeable is based on
>>   mkTyCon :: String ->  TyCon
>> which internally keeps a table mapping Strings to Ints, so that each TyCon
>> can be given a unique Int for fast comparison.  This means the String has to
>> be unique across all types in the program.  Currently derived instances of
>> typeable use the qualified original name (e.g. "GHC.Types.Int") which is not
>> necessarily unique, is non-portable, and exposes implementation details.
>> The String passed to mkTyCon is returned by
>>   tyConString :: TyCon ->  String
>> which lets the user get at this non-portable representation (also the Show
>> instance returns this String).
>> So the new proposal is to store three Strings in TyCon.  The internal
>> representation is this:
>> data TyCon = TyCon {
>>    tyConHash    :: {-# UNPACK #-} !Fingerprint,
>>    tyConPackage :: String,
>>    tyConModule  :: String,
>>    tyConName    :: String
>>   }
>> the fields of this type are not exposed externally.  Together the three
>> fields tyConPackage, tyConModule and tyConName uniquely identify a TyCon,
>> and the Fingerprint is a hash of the concatenation of these three Strings
>> (so no more internal cache to map strings to unique Ids). tyConString now
>> returns the value of tyConName only.
>> I've measured the performance impact of this change, and as far as I can
>> tell performance is uniformly better.  This should improve things for SYB in
>> particular.  Also, the size of the code generated for deriving Typeable is
>> less than half as much as before.
>> === Proposed API changes ===
>> 1. DEPRECATE mkTyCon
>>    mkTyCon is used by some hand-written instances of Typeable.  It
>>    will work as before, but is deprecated in favour of...
>> 2. Add
>>    mkTyCon3 :: String ->  String ->  String ->  TyCon
>>    which takes the package, module, and name of the TyCon respectively.
>>    Most users can just derive Typeable, there's no need to use mkTyCon3.
>> In due course we can rename mkTyCon3 back to mkTyCon.
>> Any comments?
>> Cheers,
>>         Simon
> Would this also mean typeRepKey could be taken out of the IO monad?
> That would be nice.

Ah yes, I forgot to mention the changes to typeRepKey.  So currently we have

   typeRepKey :: TypeRep -> IO Int

this API is difficult to support in the new library, I'd have to 
reintroduce the cache, and it wouldn't be very efficient.  I plan to 
change it to this:

   data TypeRepKey -- abstract, instance of Eq, Ord
   typeRepKey :: TypeRep -> IO TypeRepKey

where TypeRepKey is a newtype of the internal Fingerprint.  Now, we 
could take typeRepKey out of IO, but the Ord instance of TypeRepKey is 
implementation-defined (it provides some total order, but we don't tell 
you what it is).  So arguably we should keep the IO.  What do people think?

Obviously this is not a backwards compatible change either way.


More information about the Libraries mailing list