Field accessor type inference woes

AntC anthony_clayden at
Fri Jul 5 08:11:38 CEST 2013

> Adam Gundry <adam.gundry <at>> writes:
> > On 04/07/13 12:27, AntC wrote:
> > H-R fields are a limitation because we can't update them either. So I
> > think it's a fair question whether supporting h-r polymorphism is
> > worth the limitations?
> Yes, higher rank polymorphism is bound to cause trouble with polymorphic
> projections, and perhaps it won't matter if we limit ourselves to one or
> the other.

So with h-r fields, let's stratify the requirements:
* The current Plan tries to support holding h-r fields
  in a way backwards-compatible with H98 records.
  Why? We know that OverloadedFields are going to break some stuff.
  It's a question of which stuff is more important to not break.

* I think the real requirement is to hold an h-r value
  in a record, accessible by field name.

Consider TPDORF does this:
(see example based on one in SPJ's SORF
s     at 'Higher-Ranked polymorphic fields' )

  -- must wrap h-r values in a newtype to put them in a record.
    newtype Rev = Rev (forall a. [a] -> [a])
    data HR = HR { rev :: Rev }

  -- Has class takes 2 args, with type family for GetResult
    type instance GetResult r "rev"     = Rev
    instance Has HR "rev"                         where
        getFld HR{ rev = (Rev x) } = Rev x
                    -- can't unwrap here, 'cos can't spec Polymorphic

Then user code must unwrap the newtype at point of applying.

I think this approach also allows update for h-r values (providing they're 
wrapped) -- but I must admit I rather ran out of steam with the prototype.

TPDORF also supported type-changing update for parametric polymorphic 
fields -- but with limitations. To get round those you would have to 
revert to H98 record update -- just as the current Plan.

So I'm tending to the conclusion that cunning though it is to use 
"a functional-dependency-like mechanism (but using equalities) 
for the result type",
that is actually giving too much of a headache.

I do like the proposed sugar for constraints (r { f :: t }) => ...
But how does that play if `Has` only needs 2 args?


More information about the Glasgow-haskell-users mailing list