FW: Survival of generic-classes in ghc

Simon Peyton-Jones simonpj@microsoft.com
Mon, 25 Feb 2002 00:27:09 -0800

I had meant to send this message to the Haskell list, because I think
there may be some readers who have good ideas about it.


-----Original Message-----
From: Simon Peyton-Jones [mailto:simonpj@microsoft.com]=20
Sent: 20 February 2002 21:16
To: Patrik Jansson; Haskell Cafe List
Cc: Ralf Hinze; Johan Jeuring
Subject: RE: Survival of generic-classes in ghc

| and I know from testing earlier versions that the
| 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.
| Any comments from the implementors - does the idea "fit well"
| 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

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

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

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

Now you can write

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

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
	class ConCls c where
 	  name :: String
	  arity :: Int=20

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 =

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

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.