MakeTypeRep fingerprints be proper, robust fingerprints
A TypeRep currently looks like this:
data TypeRep = TypeRep Fingerprint TyCon [TypeRep]
data TyCon = TyCon {
tyConHash :: Fingerprint,
tyConPackage :: String,
tyConModule :: String,
tyConName :: String }
If two TypeReps have the same fingerprint they should really describe identical types.
But that's not really true today, becuase today the fingerprint for a TyCon is obtained by hashing the name of the type constructor (e.g. base:Data.Maybe.Maybe), but not its structure. To see how this is non-robust, imagine that
module M where
data T = MkT S deriving( Typeable )
data S = S1 Int | S2 Bool deriving( Typeable )
Now I do this:
- Write a program that costructs a value
v::T, and serialises into a file (a) theTypeRepforv, and (b)vitself. - Now I alter the data type declaration for
S - Now I recompile and run the program again, which attempts to read the value back in from the file. It carefully compares
TypeReps to be sure that the types are the same... yes, still "M.T". - But alas the de-serialisation fails because
Shas been changed.
What we really want is for the fingerprint in a TypeRep to really be a hash of the definition of T (not just its name), including transitively the fingerprints of all the types mentioned in that definition.
In effect, a TypeRep is a dynamic type check, and it should jolly well be a robust dynamic type check. This might also matter in a Cloud Haskell application with different components upgraded at different times.
As it happens, GHC already computes these fingerprints, to put in interface files. But they aren't used when making the Typeable instances for T. I think it should be.
Trac metadata
| Trac field | Value |
|---|---|
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture |