Hello Simon and all,

I am not sure what is the best way to proceed with the generic default
methods. But first, some context: for the new generic deriving mechanism,
being implemented in GHC [1] in a way similar to UHC [2], we need some form
of default generic methods. Taking the Eq class and (==) as example:

class Eq a where
  -- type signatures
  eq, neq :: a -> a -> Bool
  -- regular defaults
  eq a b = not (neq a b)
  neq a b = not (eq a b)

Our generic eq uses a class

class GenericEq f where
  geq :: f a -> f a -> Bool

and a default method, which takes care of conversion from a user-defined
datatype to its representation, and then applying the generic function [3]:

genericEqDefault :: (Representable0 a rep, GenericEq rep) => a -> a -> Bool
genericEqDefault a b = geq (from0 a) (from0 b)

To be able to derive generic equality for a user-defined datatype D, we need
to generate an instance Eq D where eq is genericEqDefault. That is:

instance Eq D where
  eq = genericEqDefault

So the compiler has to know that this genericEqDefault is somehow associated
to the Eq class. In UHC we used a pragma:

{-# DERIVABLE Eq eq genericEqDefault #-}

That is, class Eq has a generic method eq with default implementation
genericEqDefault.

For GHC, we first thought of something like:

class Eq a where
  ... -- all the stuff as before
  deriving eq = genericEqDefault

That is, the generic default would stay together with the class declaration,
a bit like regular defaults [4]. The problem here is that the "deriving eq"
part doesn't really typecheck under the same context as the regular default:
we need the context
(Representable0 a rep, GenericEq rep).

What is the best choice here? We could decide to accept the code above and
implicitly use the context from genericEqDefault. I'm not sure on what kind
of error messages this would result, though. Another alternative is to
decouple the generic default, as in UHC. Proper syntax for the DERIVABLE
pragma could be something like:

deriving instance (Representable0 a rep, GenericEq rep) => Eq a where
  eq = genericEqDefault

I'm happy to hear your thoughts on this.


Cheers,
Pedro

[1]
http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/GenericDeriving
[2] http://www.dreixel.net/research/pdf/gdmh_nocolor.pdf
[3] In UHC we needed to pass the representation explicitly as an argument to
genericEqDefault. In GHC, if we use FunctionalDependencies or TypeFamilies,
we can avoid this.
[4] Note that we must keep regular defaults as well, since users might want
to use the Eq class without any generics.
_______________________________________________
Cvs-ghc mailing list
Cvs-ghc@haskell.org
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to