If we put the deriving defaults together with the class definition, as normal 
defaults and as op4 in your code above, we have a somewhat strange situation, 
since the code for op4 can have some "extra context" not easily visible; 
|minimum| could be an imported function, for instance.

A naive end-user, wanting to derive C for his/her datatype T, may then write
instance C (T a)

hoping that op4 will be filled-in generically, knowing nothing about the Ord 
constraint. An error message would probably tell the user that we lack an 
instance for Ord a, which would still be very surprising since there might be 
no Ord anywhere near the definition of class C!

However, if we force the deriving defaults to be specified separately from the 
class, like
derivable instance (Ord a) => C a where
  op4 = minimum

it would hopefully be more clear to end-users that they can only derive C if 
they can satisfy the Ord constraint.

But, each derivable method might have a different context.  There's no 
particular reason to require them all to be the same, which the "derivable 
instance" you suggest would require.  Also I'm keen to stress the similarity to 
the existing H98 default-method setup.  Moreover it'd be stupid to give both a 
H98 default method in the class and a defn in the derivable-instance decl.  
Moreover what if the derivable-instance decl wasn't in the same module as the 
class decl?  It doesn't smell right to me.

How about this:
         class C a where
           op4 :: [a] -> a
           generic op4 :: (Representable a) => [a] -> a
           op4 = ....

The idea is the extra "generic" type signature for op4 specifies the type of 
the op4 to use if you don't otherwise specify one; and the accompanying code 
should have that type.  This addresses the question you raised, by combining 
(a) the construct that says "this method has a generic default" with (b) the 
construct that gives the type signature of that default.

Again the syntax by which this signature is introduced is moot.  Grabbing 
"generic" as a keyword seems reasonable to me.  I suppose we could (perhaps 
confusingly) reuse "default":

         default op4 :: (Representable a) => [a] -> a

Do you like this approach any better?  Andres?  Johan?

Simon


_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to