
Hello,
On 2/2/07, Simon Peyton-Jones
Does your proposal cover only higher-rank types for *data constructors*? Ticket 57 is about adding polymorphic components to datatypes which is why my notes tried to focus on this issue. Some of the issues are related to the ticket that proposes allowing arbitrary functions to have rank-2/N types and, of course, we should be consistent in our design.
| * Equality of schemes for labeled fields in different constructors. GHC uses equality modulo alpha conversion, but not modulo reordering of type variables or contexts. This is easy to explain to programmers, and of course it's easy for the programmer to ensure. Why would you want the more expressive semantic equality in practice? I think this a solution seeking a problem. Why complicate things? (Same goes for the predicates in the context. Let's insist they are the identical.)
I don't have a strong preference on this issue (although it would be nice if the order of the predicates did not matter, as this would be a first). Stephanie was suggesting that perhaps a more semantics comparison of schems might be useful, perhaps she has some examples?
| * Pattern matching on polymorphic fields. This does not appear to be | too controversial, although Atze had some reservations about this | design choice.
I removed this because I thought it was tricky to implement (given GHC's code structure). But I needed something very similar for associated types, so now GHC's code structure makes it easy, and I'm planning to put it back in.
It's a small thing -- I have had one or two bug reports since removing it, but it's not a feature many will miss. Still, it seems "natural" to allow it (e.g. disallowing it requires extra words in the language spec), which is why I think I'll add it.
So far, most replys seemed to agree that this is not a big restriction. Could you give more details on how you think that should work? If we follow the current rules for pattern simplification, then this feature might be a bit confusing. Here is an example:
data T = C (forall a. [a->a])
f (C (f:fs)) = ...
f x = case x of C y -> case y of f : fs -> ... _ -> undefined
Notice that in the translation, when we 'case' on the 'y' the list gets instantiated, so that 'f' is monomorphic. There is nothing wrong with that but I think that the may be more confusing than useful. -Iavor