
On Tue, May 26, 2009 at 4:32 AM, wren ng thornton
One alternative is to use Haskell's support for ad-hoc overloading. Define a typeclass for each selector (or group of selectors that must always occur together) which is polymorphic in the record type. [...] It's not pretty, but it gets the job done. Many people decry this as improper use of typeclasses though (and rightly so).
Yes. I was experimenting a little with type classes and the more granular I defined them the more I got the feeling of producing a hack. But as you said, it would get the job done and I will probably give it a try.
A better approach would probably be to use GADTs or the new data families which give a sort of dual of typeclasses (typeclasses give a small set of functions for a large set of types; GADTs give a large set of functions for a small set of types[0]). Someone more familiar with those approaches should give those versions.
Interesting, but I fail to see how this might be applied to the problem at hand. I played with associated types and they are quite neat. But I would still be working with type classes, so how would this be different from the first approach. W.r.t. GADTs I understood these as to provide a way to be more specific about the return type of constructor functions. But my problem is mostly a scope issue, isn't it?
If you want to be able to set the fields as well as read them then the classes should be more like lenses than projectors.
I am fine with selectors for now. But thanks for the references.
Also take a look at hptotoc[4], the Haskell implementation of Google's Protocol Buffers which has many similar problems to your Bayeaux protocol. In general, protocols designed for OO are difficult to translate into non-OO languages.
From what I saw by briefly scanning the contents it seems to me the problem is again solved with the type class approach you mentioned in the beginning.
I wonder if I am completely off here, but I am surprised that there is no progress on the scoped labels front. The Haskell wiki mentioned that the status quo is due to a missing optimum in the design space, but the same can be said about generic programming in Haskell and yet, GHC ships with Scrap your boilerplate. So we have to resort to type classes hacks instead of a proper solution. OTOH I might not have understood the relevance of GADTs for this problem and it is a non-issue but prima facie it doesn't seem to be. Anyway, many thanks for your thoughtful reply. Best regards, nt