Thinking about this more, I realise that the "right" place for the Typable 
instance is the type-constructor declaration itself.  We should not have a 
Typeable instance for each indexed type; rather just one for the whole type.  
Thus

        data family T :: *->*
        instance Typeable1 T where
          typeOf1 _ = ...

        data instance T [a] = T1 a | T2 deriving( Eq )

We could not define Eq on T; it must be done per-instance. But we can define 
Typeable on T; and indeed we should do so; it seems silly to have lots of 
instances.

I'm not quite sure how to do this.
        data family T :: * -> * deriving( Typeable )
Or with separate deriving (which I like)
        derive Typeable a => Typeable (T a)


Does that make sense?

Simon

| -----Original Message-----
| From: Manuel M T Chakravarty [mailto:[EMAIL PROTECTED]
| Sent: 20 December 2006 17:30
| To: Simon Peyton-Jones
| Cc: [EMAIL PROTECTED]
| Subject: RE: patch applied (ghc): Deriving for indexed data types
|
| Simon,
|
| > |   - We cannot derive Typeable.  This seems a problem of notation,
| more
| > | than
| > |     anything else.  Why?  For a binary vanilla data type "T a b",
| we
| > | would
| > |     generate an instance Typeable2 T; ie, the instance is for the
| > | constructor
| > |     alone.  In the case of a family instance, such as (S [a] (Maybe
| > | b)), we
| > |     simply have no means to denote the associated constuctor.  It
| > | appears to
| > |     require type level lambda - something like (/\a b. S [a] (Maybe
| b).
| >
| > Suppose you have an indexed data type with kind
| >         T :: * -> * -> * -> *
| > Of these parameters, suppose 2 are type indices and 1 is fully
| polymorphic.
|
| Just to ensure that I understand exactly what you mean, for indexed
| data
| types (as opposed to indexed synonyms) we dropped this whole arity
| business and distinction between arguments that can be indexes and
| others that must be parametric.  (We can drop that distinction for
| indexed data types as they only ever induce injective type functions;
| ie, ones for which decomposition is valid.)
|
| However, for every individual instance of an indexed data type, we
| could
| peel of any trailing variable-only arguments.  (Somewhat like the eta
| business for newtype deriving.)  So, for
|
|   data instance T [a] b = ... deriving Typeable
|
| we could generate
|
|   instance Typeable a => Typeable1 (T [a]) where ...
|
| However, for
|
|   data instance T [a] (Maybe b) = ... deriving Typeable
|
| we would generate
|
|   instance (Typeable a, Typeable b) => Typeable (T [a] (Maybe b)) where
| ...
|
| So, for different instances of the same family, we would use different
| TypeableX classes.  Do you think that might be too confusing.
|
| > Then shouldn't we generate an instance for Typeable1, *not*
| Typeable3:
| >         instance (Typeable a, Typeable b) => Typeable1 (T a b)
| where...
| >
| > Then there is no difficulty about generating its type representation
| is there?
|
| I didn't look at the type representation yet, as I stumbled over the
| mentiond issue first.  But I think it should be ok.
|
| Manuel
|

_______________________________________________
Cvs-ghc mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to