
Simon Peyton-Jones
| What would really, really help me is for someone to have a look at
the 'solution' I
| posted to the difficulties SPJ saw with the SORF approach. (I ref'd it in my reply to
In response to your plea, I took a look at your post http://www.haskell.org/pipermail/glasgow-haskell-users/2011- December/021298.html
Thank you Simon for putting in the time. I hope you feel it advanced the discussion.
Some thoughts
* I don't think you need GetTy at all. The attached version of your code gets rid of it.
[Sorry, but no attachment seems to have come through in any of the places I looked. I'm glad if we can simplify the code. I was trying to give type inference as much help as possible, in case we could work 'outside in' from the type of the result.]
* Your trick with SetrTy does, I think, support type-changing update. Good. (Whether type-changing update is itself a valuable enough feature to be worth the extra complexity, I'm not certain, but perhaps that's a separate matter.)
Thank you. I, too, doubt its value. I'm thinking mostly about database applications, where it would be a BAD THING.
* Your trick with SetTy to support update of polymorphic fields is, I belive, an (ingenious) hack that does not scale. I think it works only for fields that are quantified over one type variable with no constraints.
I'll take a merit point for the "ingenious", and a demerit for the "hack", which of course it is. We can introduce arbitrarily many forall'd type variables in the class definition for set and SetTy: set :: fld -> (forall a_ b_ c_ d_. SetTy r fld t a_ b_ c_ d_) -> ... I'm guessing I'll get no extra merits for that, and only multiply the demerits. Re the constraints, does anything in the 7.4.1 Constraint Kinds help? Is there any plan/could there ever be constraints on the RHS of type families? Having an unconstrained `set' perhaps(?) doesn't do any harm, because we can constrain what the corresponding `get' digs out (in the instance header for Has). See my example instances for fldn and fldnb.
So, I think that update of polymorphic fields remains problematic.
Yes. So I don't see this being a drama for people wanting records for databases (where you can't save polymorphic functions to persistent media). But it is problematic for the object-oriented oriented, OK so now my part of the deal is to write up a full proposal on the wiki. (Always I hear time's winged chariot hurrying near.) My tactic is to write snippets in response to the various threads, then try to gather them together to a cogent whole. The key element is that the compiler generates the Has instances from the data decl, and the programmer wouldn't see them. So perhaps we could get away with them being ugly and/or hacks and/or limited scalability. (I'm not proposing any changes to data decls, but the syntactic sugar for record type notation in constraints would be handy.) Before you ask: virtual record selectors like fullName or area would be just ordinary functions, not field-like [This gets us out of your difficulty with a `set' for virtual fields - there just wouldn't be one.]: fullName r = r.firstName ++ " " ++ r.lastName so ordinary type inference for the Has constraints, derived from using the field selectors: fullname :: (Has r Proxy_firstName String, Has r Proxy_lastName String) => r -> String or with the sugar: fullName :: r { firstName, lastName :: String } => r -> String Not only virtual selectors but also field-name selectors are just ordinary functions, so can be blocked from import/export. [This gets past the Representation hiding difficulty.] set and get are ordinary (overloaded) functions [although we might not allow them to appear direct in code]. So they (or field acces built over them) can be passed around polymorphically, applied to polymorphic records, etc. Anthony