Overloaded record fields

AntC anthony_clayden at clear.net.nz
Sun Jun 30 13:36:07 CEST 2013

> Malcolm Wallace <malcolm.wallace <at> me.com> writes:
> I believe Simon's point is that, if dot is special, we can infer 
the "Has" type above, even if the compiler is
> not currently aware of any actual record types that contain a "foo" 
field. ...
> (For the record, I deeply dislike making dot special, ...

Simon, Malcolm, here's a solution (at risk of more bikeshedding on syntax).

    e { foo }

  * The braces say 'here comes a record'.
  * Also say 'expect funny business with names'.
  * The absence of `=` says this is getFld, not update.
  * This is not currently valid syntax [**], so we don't break code.
  * It's postfix. (And only a couple more chars than infix dot.)
  * So perhaps an IDE can see the opening brace and prompt for fields?
    (Perhaps some IDE's do this already for record update?)
  * If we need to disambiguate the record type:

    e :: T Int { foo }       -- as the Plan suggests for record update

Development would fit into the 'sequence of attack' as 5b., with record 
update syntax.

[**] ghc 7.6.1 rejects the syntax, and suggests you need NamedFieldPuns.
     But if you set that, you get a weird type error,
     which suggests ghc is de-sugaring to { foo = foo }.
     We'd have to fix that.

The syntax is valid in a pattern (with NamedFieldPuns).
Indeed the proposed syntax echoes pattern match:

    e .$ (\ (MkFoo { foo }) -> foo )       -- (.$) = flip ($)

We'd better insist NamedFieldPuns is on to allow the proposal.
Otherwise the syntax would have to be:

    e { foo = foo }     -- ambiguous with update

In fact the proposal is an enhancement to NamedFieldPuns,
'repurposed' for OverloadedRecordFields.

Possible future development:

    e { foo, bar, baz }  -- produces a tuple ( _, _, _ )
                         -- with fields in order given
                         -- _not_ 'canonical' order in the data type

  * By coincidence, that syntax is per one of the dialects for
    relational algebra projection over a tuple.

  * Possibly useful for overloaded comprehensions?:

    [ x { foo, bar, baz } | x <- xs ]

    [ { foo, bar } | { foo, bar, baz } <- xs, baz = 27 ]


More information about the Glasgow-haskell-users mailing list