Changes between Version 6 and Version 7 of Records/OverloadedRecordFields/Plan


Ignore:
Timestamp:
Jun 18, 2013 4:57:15 PM (10 months ago)
Author:
adamgundry
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Plan

    v6 v7  
    1 This is a plan to implement overloaded record fields, along the lines of SPJ's [wiki:Records/OverloadedRecordFields Simple Overloaded Record Fields] proposal, as a Google Summer of Code project. (See the [http://www.google-melange.com/gsoc/proposal/review/google/gsoc2013/adamgundry/1 original GSoC proposal], for reference.) The page on [wiki:Records Records] gives the motivation and many options.  In particular, the proposal for [wiki:Records/DeclaredOverloadedRecordFields Declared Overloaded Record Fields] is closely related but makes some different design decisions. 
     1= Overloaded record fields: a plan for implementation = 
     2 
     3This is a plan to implement overloaded record fields, along the lines of SPJ's [wiki:Records/OverloadedRecordFields Simple Overloaded Record Fields] proposal, as a Google Summer of Code project. (See the [http://www.google-melange.com/gsoc/project/google/gsoc2013/adamgundry/23001 GSoC project details], for reference.) The page on [wiki:Records Records] gives the motivation and many options.  In particular, the proposal for [wiki:Records/DeclaredOverloadedRecordFields Declared Overloaded Record Fields] is closely related but makes some different design decisions. 
    24 
    35 
     
    68'''SLPJ''' this section should be a careful design specfication. 
    79 
    8 === Motivating example === 
    9  
    10 {{{ 
    11 {-# LANGUAGE OverloadedRecordFields #-} 
    12  
     10=== Motivation === 
     11 
     12A serious limitation of the Haskell record system is the inability to overload field names in record types: for example, if the data types 
     13 
     14{{{ 
    1315data Person  = Person  { personId :: Int, name :: String } 
    1416data Address = Address { personId :: Int, address :: String } 
    15  
     17}}} 
     18 
     19are declared in the same module, there is no way to determine which type an occurrence of the personId record selector refers to. A common workaround is to use a unique prefix for each record type, but this leads to less clear code and obfuscates relationships between fields of different records. Qualified names can be used to distinguish record selectors from different modules, but using one module per record is often impractical. 
     20 
     21Instead, we want to be able to write postfix polymorphic record projections, so that `e.personId` resolves the ambiguity using the type of `e`. In general, this requires a new form of constraint `r { x :: t }` stating that type `r` has a field `x` of type `t`. For example, the following declaration should be accepted: 
     22 
     23{{{ 
    1624getPersonId :: r { personId :: Int } => r -> Int 
    17 getPersonId x = x.>personId 
     25getPersonId e = e.personId 
    1826}}} 
    1927 
    2028=== Record field constraints ===  
     29 
     30'''AMG''' the following needs updating. 
    2131 
    2232If the flag `-XOverloadedRecordFields` is enabled, a new form of 'record field' constraints `r { x :: t } :: Constraint` are available where `r` and `t` are types, while `x` is a literal string.  These are not typeclass constraints and do not have instances as such (though see the discussion below about virtual record fields). They can appear in contexts in the usual way (that is, they are a new primitive, like equality constraints or implicit parameter constraints). Multiple fields may be written comma-separated in a single constraint as in `r { x :: t, y :: u }`.