Survival of generic-classes in ghc

Simon Peyton-Jones simonpj@microsoft.com
Wed, 20 Feb 2002 13:15:36 -0800


| and I know from testing earlier versions that the=20
| generic-classes support was pretty buggy. Is there any hope=20
| of a revival? Does it already work in CVS? I suspect it will=20
| rot away if nobody works on it.
|=20
| Any comments from the implementors - does the idea "fit well"=20
| with ghc? Is it a lot of work to make it more stable?

No, it should not be a lot of work to revive, and I will do it.
Keep bugging me until I do.=20

One thing that is slowing me down is a design uncertainty: how to deal
cleanly with constructors.  To write read, show, etc, one needs access
to
the constructor name, fixity etc.  We dance around that a little in the
paper.
I'm thinking of this design:

-- An example data type
data List a =3D Nil | Cons a (List a)

-- The "ring" type derived from it
-- Note the Con wrapped around the constructors
data ListO a =3D Con NilT 1 :+: Con ConsT (a :*: List a)

-- Con is part of the Generics library, like 1, :*:, :+:
newtype Con c a =3D Con a

class ConCls c where
   name :: c -> String
   arity :: c -> Arity
   ..etc..

data NilT	-- Phantom types
data ConsT	-- one per constructor

instance ConCls NilT where
   name _ =3D "Nil"
   ...etc...

instance ConCls ConsT wher
    name _ =3D "Cons"
   ...etc...

Now you can write

   class Show a where
      show :: a -> String
      show {| Con c t |} (Con x) =3D (name (undefined::c)) ++ show x
	...etc..


Note the "undefined::c"; it is really just a type argument to "name", so

that we get the string for the right constructor.  It's a bit clunky,
though.
Another possiblity would be to make the ConCls class look like this
	class ConCls c where
 	  name :: String
	  arity :: Int=20
	  ...etc...

Now we'd have to give an explicit type argument at the call site:

      show {| Constr c t |} (Con x) =3D (name {| c |}) ++ show x

I quite like the thought of being able to supply explicit type
arguments....
but I don't konw how to speak about the order of type parameters.
What order does map takes its two type parameters in?


Another question is whether we need an indication that we have reached=20
a field of the constructor.  Should we have:

data ListO a =3D Con NilT (Field 1) :+: Con ConsT (Field a :*: (Field =
List
a))

newtype Field a =3D Field a


Without this, it's hard to write a generic function to count the number
of
fields of the data type.  But in general, one might want to know when
making the transition from "this" type to the argument types of  the
constructors.


I think that the main reason I'm not making much progress is that I
don't
know what design choices to make.  I'd be glad to discuss it with
interested
parties.

Simon