Generic deriving: new default methods

Simon Peyton-Jones simonpj at microsoft.com
Wed Jan 12 12:13:49 CET 2011



| -----Original Message-----
| From: andres.loeh at googlemail.com [mailto:andres.loeh at googlemail.com] On
| Behalf Of Andres Loeh
| Sent: 12 January 2011 08:48
| To: Simon Peyton-Jones
| Cc: José Pedro Magalhães; Johan Jeuring; cvs-ghc at haskell.org; atze
| Subject: Re: Generic deriving: new default methods
| 
| Hi.
| 
| Just for fun, I'm trying:
| 
| > Harumph.  Well that would involve a new nest of design issues
| >
| > * What if there was more than one generic default visible?
| 
| At the moment when the default would be used (i.e., once we try to
| derive an instance), if there's more than one default visible a clash
| would be reported. This lazy reporting seems to be in the style of
| what's done in Haskell elsewhere.
| 
| > * What if a class had both a H98 default for a method, and a "later"
| generic default?
| 
| Either again, a lazy clash could be reported, but it might also make
| sense to say that the generic default wins in this case.
| 
| > * Could the generic defaults be overlapping? eg
| >        generic instance Representable a => C a where
| >          op4 = blah
| >        generic instance Representable a => C [a] where
| >          op4 = blah-list
| 
| So the above syntax means that a generic instance *could* be created
| with this definition, right? We still need a separate instruction to
| actually trigger the deriving. Then again, I'd say a clash should be
| reported if due to the overlap, two defaults are available at the
| point where the instance is derived.
| Of course, it's possible here to think about more clever approaches
| such as interacting with OverlappingInstances and selecting the most
| specific one.
| 
| > * What does it mean for a generic default to be "visible" anyway?  I
| suppose you could say "use the same rules as instance declarations, but those
| rules are horrible.
| 
| True enough. Those are the ones I'd use, though. The problem of them
| being horrible should be fixed in a separate attempt, and would
| hopefully solve the issue for both.
| 
| > * Can different methods (op3 and op4) have different generic defaults?  eg
| >        generic instance Representable a => C a where
| >          op3 = blah3
| >
| >        ...and somewhere else...
| >
| >        generic instance Foogle a => C a where
| >          op4 = blah 4
| 
| Well, this, I thought, was one of the things you actually wanted.
| Namely to be able to say
| 
| class C a where
|    ...
|    op3 :: ...
|    generic
|       op3 :: Representable a => ...
|       op3 = blah3
|    generic
|    op4 :: ...
|       op4 :: Foogle a => ...
|       op4 = blah4
| 
| even if blah3 and blah4 have completely different contexts? So this
| question seems unrelated of the question whether we can define generic
| defaults separately from a class or have to put them in the class
| definition.
| 
| > * How do generic instances differ from ordinary (overlapping) instances.
|  They are pretty close as you can see above.
| 
| I don't understand this question.
| 
| > Now there are legitimate questions about "superclass defaults" etc, see
| http://hackage.haskell.org/trac/ghc/ticket/788 and
| http://hackage.haskell.org/trac/ghc/ticket/2895.  But I don't want to
| conflate the two.
| >
| > So for my money, I say let's stick to the H98 mechanism, of specifying
| defaults with the class, and treat the issue of overriding etc separately.
| 
| Ok, fine with me. I think a syntax that provides the type signature
| with the default is fine then. The extra type signature could even be
| made optional then. Then the library author can decide whether the
| class constraint should be provided for documentation purposes or not.
| 

| > Or can you see simple answers to the above?
| 
| I don't claim my answers are simple. I just wanted to make sure we've
| discussed this briefly, but I'm happy to decide against it.

I agree that answers can be provided, but
 * It's a lot of new design choices, 
 * I believe this new feature (decoupling the class decl from the
	provision of default methods) will require a *lot* of new hacking
 * No one is asking for this feature
 * Moreover, there are open design threads that intersect these issues;
       http://hackage.haskell.org/trac/ghc/ticket/788 and
       http://hackage.haskell.org/trac/ghc/ticket/2895
  If we plump now for one choice or another we might have to rewind that choice later.

| Ok, fine with me. I think a syntax that provides the type signature
| with the default is fine then. The extra type signature could even be
| made optional then. Then the library author can decide whether the
| class constraint should be provided for documentation purposes or not.

Well, no.  I suggest that the "generic-default" signature is precisely what announces that there's a generic-default method.  If you don't add such a signature, you get the H98 mechanism.  Thus

	class C a where
 	  cop :: a -> a
	  cop = \x -> x

	class D a where
	  dop :: a -> a
	  generic dop :: Representable a => a -> a
  	  dop = ...code...

Here, cop is a normal H98 default, while dop is a derivable-type-class default.  In my proposal it's the 'generic' keyword on the signature tells you which is which.

Simon



More information about the Cvs-ghc mailing list