Magic classes for Overloaded Record Fields, overlaps, FunDeps

AntC anthony_clayden at
Wed Apr 27 01:55:00 UTC 2016

> > On 26/04/16 09:20, AntC wrote:
> > There's an intriguing comment here wrt anonymous records: ...
> I'm afraid the sentence on the wiki page is slightly misleading, ...
>  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]. 

Thanks Adam, we're very much thinking along the same lines.

Yes that's exactly where I am at.
I too like the error message re overlapping instances.

Contrast that for an HList style solution,
you get instance match on the leftmost/outermost appearance
of the label. So to detect duplicates you need a `Lacks`
superclass constraint on the HList's tail.
And to get `Lacks` to work,
you need to create an instance;
for which you then need an impossible-to-fulfill
superclass constraint.
Even with the best of documentation,
you get a dense error message,
quite possibly pointing to the wrong place.

So unlike HLists, Nikita's Record<n>s are 'flat'
(same as if you used plain tuples)
and the instance matcher can look at all elements at the same time.

Furthermore (closed) type families suffer a similar difficulty.
The instance equations are ordered, so will pick the leftmost
(or rightmost) appearance without complaint.
To detect ambiguous getFields you need first a guard equation
   HasField n1 (Record2 n1 v1 n1 v2) = error: overlap

For a two-tuple that's OK.
For more than two you need guard equations
for all of the ambiguous perms and combs.
For a 24-tuple that's horrendous.
For tuple extension or joining your head explodes.

Even if we could automate generating the ambig instances somehow,
it just feels wrong to get an instance/equation match
when what you want is an error.

> 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!

Yes, this seems a 'featurette' of Overlaps/FunDeps
compared to closed type families.
Should I regard it as a 'happy accident'
 that might stop working some day?
It does seem a pretty fundamental requirement for Overlaps
-- providing of course IncoherentInstances is never switched on
in some distant module.

> 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. ...

Thanks. Yes I'm aware of that approach from HList.
It works a little more nicely with type families.

The difficulty remains that as soon as you want overlaps
in such a way that takes you to FunDeps,
it's very difficult to 'mix modes' with type families.


> [1]

More information about the Glasgow-haskell-users mailing list