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


Ignore:
Timestamp:
Sep 20, 2013 3:55:06 PM (7 months 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