Changes between Version 17 and Version 18 of Records/OverloadedRecordFields/Implementation


Ignore:
Timestamp:
Jul 30, 2013 5:38:03 PM (9 months ago)
Author:
adamgundry
Comment:

disambiguating record updates

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Implementation

    v17 v18  
    4343where the first component is the field and the second is the selector function (TODO: dfun name). 
    4444 
    45 Where an AST representation type (e.g. `HsRecField` or `ConDeclField`) contained an argument of type `Located id` for a field, it now stores a `Located RdrName` for the label and `Maybe id` for the selector. The parser supplies `Nothing` for the selector; it is filled in by the renamer  (by `rnHsRecFields1` in `RnPat`, and `rnField` in `RnTypes`). Partial functions are provided to extract the `Located id`, but they will panic if called on not-yet-renamed syntax.  '''SLPJ''' Consider using `(error "not yet filled in")` instead of a `Maybe`.  We do that quite a lot. '''AMG''' Done for `ConDeclField`. I need to think about how to change `HsRecField` in order to support the more liberal rules for record updates. 
    46  
    4745 
    4846== Source expressions == 
     
    5149 
    5250When the flag is not enabled, `rnExpr` turns an unambiguous record field `foo` into `HsSingleRecFld foo $sel_foo_T`. The point of this constructor is so we can pretty-print the field name but store the selector name for typechecking. 
     51 
     52Where an AST representation type (e.g. `HsRecField` or `ConDeclField`) contained an argument of type `Located id` for a field, it now stores a `Located RdrName` for the label, and some representation of the selector. The parser uses an error thunk for the selector; it is filled in by the renamer  (by `rnHsRecFields1` in `RnPat`, and `rnField` in `RnTypes`). The new definition of `ConDeclField` (used in types) is: 
     53 
     54{{{ 
     55data ConDeclField name 
     56  = ConDeclField { cd_fld_lbl  :: Located RdrName, 
     57                   cd_fld_sel  :: name, 
     58                   cd_fld_type :: LBangType name,  
     59                   cd_fld_doc  :: Maybe LHsDocString } 
     60}}} 
     61 
     62The new definition of `HsRecField` is: 
     63 
     64{{{ 
     65data HsRecField id arg = HsRecField { 
     66        hsRecFieldLbl :: Located RdrName, 
     67        hsRecFieldSel :: Either id [(id, id)], 
     68        hsRecFieldArg :: arg, 
     69        hsRecPun      :: Bool } 
     70}}} 
     71 
     72The renamer (`rnHsRecFields1`) supplies `Left sel_name` for the selector if it is unambiguous, or `Right xs` if it is ambiguous (because it is for a record update, and there are multiple fields with the correct label in scope). In the latter case, the possibilities `xs` are represented as a list of (parent name, selector name) pairs. The typechecker (`tcExpr`) tries three ways to disambiguate the update: 
     73 
     741. Perhaps only one type has all the fields that are being updated. 
     75 
     762. Use the type being pushed in, if it is already a `TyConApp`.  
     77 
     783. Use the type signature of the record expression, if it exists and is a `TyConApp`. 
    5379 
    5480 
     
    96122== To do == 
    97123 
    98 Typechecking of record updates still uses the first field to determine the type, so the renamer has to produce unambiguous selector names. It should be possible to specify the record type via a type signature, so `rnHsRecFields1` needs to be a bit more liberal. 
    99  
    100124Only projection is implemented, not update, so there is no lens integration. We need to decide on a story here. 
    101125