Changes between Version 38 and Version 39 of Records/OverloadedRecordFields/Plan


Ignore:
Timestamp:
Sep 20, 2013 3:55:06 PM (2 years ago)
Author:
adamgundry
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Plan

    v38 v39  
    331331A. The code still compiles correctly.
    332332
    333 An advantage of distinguishing record projections syntactically (as in `x.g`) is that `g` is always treated as a record field, regardless of what is in scope. This allows better separation of concerns, as functions that manipulate records can be defined abstractly rather than referring to particular datatypes. We could consider using an operator less controversial than dot (for example, `(|:)` has been suggested), or a keyword such as '''select''':
    334 
    335 {{{
    336 f x = x|:g + 1
    337 f x = select g x + 1
    338 }}}
    339 
    340 
    341 === Introducing field names ===
    342 
    343 As noted above, sometimes one might want to write code that uses record fields without any particular record types being in scope. One workaround is to define unused types with the appropriate field names. This is slightly odd! We might consider adding a new declaration form, say '''field''' `g`, which declares `g` as a record field that is always polymorphic, rather like the function declaration
    344 
    345 {{{
    346 g :: r { g :: t } => r -> t
    347 g = field
    348 }}}
    349 
    350 but with the property that it will not clash with actual `g` fields.
     333
     334=== Syntax for record projections ===
     335
     336An advantage of distinguishing record projections syntactically (as in `x.g`) is that `g` is always treated as a record field, regardless of what is in scope. This allows better separation of concerns, as functions that manipulate records can be defined abstractly rather than referring to particular datatypes. We could consider using an operator less controversial than dot (for example, `#` has been suggested):
     337
     338{{{
     339f x = x#g + 1
     340bar xs = map (#baz) xs
     341}}}
     342
     343This should not conflict with `-XMagicHash`, since that allows `#` only as a postfix name modifier. Note that it works perfectly with partial application.
     344
     345Another alternative, once we have `-XExplicitTypeApplication`, is to use the `field` function defined in `GHC.Records`:
     346
     347{{{
     348field @"foo"
     349}}}
     350
     351That is a bit long, however, and worse is the version needed at present:
     352
     353{{{
     354field (Proxy :: Proxy "foo")
     355}}}
    351356
    352357
     
    370375
    371376This gives the maximum amount of polymorphism and the right behaviour in the presence of the monomorphism restriction, but defaulting is evil and confusing...
     377
     378At the moment we take the first option.
    372379
    373380