Andre Pang <[EMAIL PROTECTED]> writes: > Hi all, I'm trying to get a grip on the Dynamic types stuff supplied > with GHC, and I'm not sure if I'm doing something wrong, or whether > I've found a bug.
Your Typeable instance looks like this: > instance Typeable FootnoteData where > typeOf _ = mkAppTy (mkTyCon "FootnoteData") [typeOf ("Foo" :: String), typeOf (7 >:: Int)] This should be written: > instance Typeable FootnoteData where > typeOf _ = mkAppTy fdtc [typeOf ("Foo" :: String), typeOf (7 :: Int)] > > fdtc = mkTyCon "FootnoteData" That is, the TyCon definition has to be a CAF (i.e., a top level definition with no arguments). The reason is somewhat grubby but comes down to 'things go much faster if you do this'). Here's the relevant comment from the code: -- If we enforce the restriction that there is only one -- @TyCon@ for a type & it is shared among all its uses, -- we can map them onto Ints very simply. The benefit is, -- of course, that @TyCon@s can then be compared efficiently. -- Provided the implementor of other @Typeable@ instances -- takes care of making all the @TyCon@s CAFs (toplevel constants), -- this will work. -- If this constraint does turn out to be a sore thumb, changing -- the Eq instance for TyCons is trivial. We've seen several bug reports of this form lately - can someone change the representation/ implementation to something a little less fragile? Three possibilities spring to mind: 1) The original slow implementation which uses string comparisions. This could be speeded up using unsafePtrEquality in the normal (Lisplike) way. 2) Maintain a table of all TyCons (or the stablename table??) When a TyCon thunk is evaluated, it looks itself up in the TyCon table inserting itself if necessary and updates itself with an index into the table. 3) Same as (2) except that if the lookup succeeds it knows there are two independent TyCons for the same string. One of two things must have happened: 1) Two independent types (perhaps in different modules) used the same string as their TyCon identifier. Yoiks! Report it as an error. 2) Someone forgot to make their TyCon a CAF. This could be made to work (using implementation strategy 2) but it will be slow. Best thing to do is report the problem and have the programmer fix it. I favour 1 or 3. While we're at it, I'd like to repeat my request that the word 'unsafe' be made part of the classname Typeable or the method name typeOf. The reason is that a badly written Typeable definition can break typesafety. Here's a superficially plausible but broken instance for IO which demonstrates it > instance Typeable (IO a) where > typeOf _ = mkAppTy iotc [] > > iotc = mkTyCon "IO" With this definition typeOf (return 1 :: IO Int) == typeOf (return () :: IO ()) and so you can coerce back and forth between these types using from/toDynamic. [A better fix would be for compilers to generate the (somewhat tricky) Typeable instances themselves.] -- Alastair Reid [EMAIL PROTECTED] http://www.cs.utah.edu/~reid/ _______________________________________________ Glasgow-haskell-users mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/glasgow-haskell-users