[Haskell-cafe] generics question, logical variables
simonpj at microsoft.com
Mon Sep 19 04:18:07 EDT 2005
I'm a bit snowed under at the moment with the POPL PC meeting, but I'm
quite open to changing GHC's "deriving" behaviour. It's not hard to
change. The hard thing is figuring out just what the specification
So if you and others are able to evolve a better design, I'd be happy to
implement it. (And of course think about it too.)
I'm afraid that full-blown kind polymorphism is probably a bit of a
stretch, though it comes up every now and again. So the best
monomorphic compromise would be good.
There's also the question of whether we should make any changes in GHC's
libraries to take SYB3 (using classes) into account...
| -----Original Message-----
| From: Ralf Lammel
| Sent: 19 September 2005 04:34
| To: frederik at ofb.net
| Cc: haskell-cafe at haskell.org; Simon Peyton-Jones
| Subject: RE: [Haskell-cafe] generics question, logical variables
| Hi Frederik,
| [I call this "the dreadful lack of kind polymorphism strikes back"
| I put SPJ on cc; perhaps he can suggest a way to improve in this area.
Based on input, I could try to
| work on this issue in the not so remote future.
| Let me briefly recapitulate. My recollection is that deriving works
for Typeable, Tyepable1, ..., if all
| type parameters are of type kind "*". Whenever you can derive a
Typeablen instance with n > 0, you
| can instead ask for Typeable to be derived. The reason why you cannot
get both a Typeable and say a
| Typeable42 instance is that there are generic instances for getting an
"n-1 instance" from the "n
| instance". However, this is also precisely the reason why you don't
want them both. That is, you get
| everything you can ask for, if you have the "n instance" for the
actual arity of the type constructor in
| question. (Getting a smaller n or no n just means that you limit
polymorphic type case.) Recall that
| you *may* need a n>0 instance if you want to do polymorphic type case
according to the SYB2 paper.
| As long as you are fine with monomorphic generic function extension,
the plain Typeable instance
| should be fine.
| However, the real limitation is here, *indeed*, as said, that GHC does
not derive Typeable[1|2|...] for
| parameter kinds other than "*". This was the reason that I had to
hand-code some Typeable instances
| in your original example.
| Let us also be honest about another limitation of the current deriving
code. "deriving Data" gives you
| Data instances that do *not* support polymorphic type case. That is
the following code prints 0, 1, 0
| whereas you may expect 0, 1, 2.
| newtype Foo x = Foo x deriving (Typeable, Data)
| f :: Data a => a -> Int
| f = const 0
| `ext1Q` (\(_::Maybe x) -> 1)
| `ext1Q` (\(_::Foo y) -> 2)
| main = do
| print $ f True
| print $ f (Just True)
| print $ f (Foo (Just True))
| This is the reason that I had to handcode some Data instances in your
original example, which wasn't
| hard BTW. We thought that these two limitations were Ok since we
didn't expect people to write many
| polymorphic datatype constructors on which SYB should work. Sounds
like a feature request.
| Now I wonder how much work it is to improve the situation. We need to
make the GHC deriving code
| a bit more kind-aware. I guess we are still not at the point where we
want to add kind polymorphism
| to Haskell? Would be a nice topic for future work on SYB. Clearly, the
GH folks have done splendid
| work in this area. Getting full-blown kind polymorphism in normal
Haskell though seems to be less of a
| topic, simply because we do not have many scenarios around that would
*really* require it.
| Does anyone want to speak up and mention scenarios that would benefit
from kind polymorphism? (In
| Haskell, we are likely to see kind polymorphism, if at all, in the
form of type classes whose type
| parameters can be of different, perhaps of all kinds.)
| Frederik, for the time being I propose to look into TH code for
deriving Tyepable/Data instances and to
| make it fit for your purposes. There are several versions of Ulf
Norell's code around. You may also use
| SYB3 with the TH code that readily comes with it.
| Thanks for bringing this up.
More information about the Haskell-Cafe