Hi AntC, On 26/04/16 09:20, AntC wrote: > There's an intriguing comment here wrt anonymous records: > https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/ > MagicClasses#Designextension:anonymousrecords > (End of the section) > > "... this doesn't quite work, because the two instances overlap, > but it is possible with a bit more trickery" > > I could well understand if everybody's forgotten what was the "trickery", > because ORF has been so long in the pipeline, but could anyone explain?
I'm afraid the sentence on the wiki page is slightly misleading, as it dates from the type families version of the HasField proposal, rather than the functional dependencies version, and the page hasn't been updated properly. In fact, with the change to functional dependencies, the overlapping instances solution works rather nicely, in that it works if the field labels are distinct and reports an error if not [1]. I'll update the page. I have been vacillating between type families and fundeps for the ORF classes. I hadn't fully appreciated this point about overlap, but I think it is a reason to prefer fundeps, which is the direction in which I'm leaning. I'd be grateful for feedback on this issue though! > Reason for the q: I'm looking at anonymous records myself, > including extending, shortening and joining anon records. > And yes overlapping instances are everywhere. > > Using type families isn't being too ergonomic. And I notice ORF has used > FunDeps. > But for me, FunDeps in the HList style is also rather ugly. > > Is there some trickery I'm missing? In general, to avoid overlapping instances, one trick is to introduce a closed type family that discriminates between the parameters, along with an auxiliary class whose instances match on the result of the type family. For example, rather than instance C [Int] instance C [a] one can write class IsInt a ~ b => CHelper a b instance CHelper Int True instance IsInt a ~ False => CHelper a False type family IsInt a where IsInt Int = True IsInt a = False instance CHelper a (IsInt a) => C [a] This allows one to write instances using top-to-bottom matching, like closed type families, provided all the instances are declared together. Hope this helps, Adam P.S. If you have any thoughts on the interaction between ORF and encodings of anonymous records, I'd be interested to hear them. [1] https://gist.github.com/adamgundry/7292df8cef62fd6750885be3f5f892e7 -- Adam Gundry, Haskell Consultant Well-Typed LLP, http://www.well-typed.com/ _______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users