Changes between Version 43 and Version 44 of Records/OverloadedRecordFields/Implementation


Ignore:
Timestamp:
Aug 16, 2013 4:20:41 PM (8 months ago)
Author:
adamgundry
Comment:

new FieldLabel? story / contemplate -XOverloadedRecordFieldInstances

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Implementation

    v43 v44  
    2525$dfUpdTx = Upd { setField _ s e = s { x = e } } 
    2626 
    27 axiom TFCo:R:GetResult : GetResult T "x" = Int   -- corresponds to the GetResult type family instance 
    28 axiom TFCo:R:SetResult : SetResult T "x" Int = T -- corresponds to the SetResult type family instance 
     27axiom TFCo:R:GetResultTx : GetResult T "x" = Int   -- corresponds to the GetResult type family instance 
     28axiom TFCo:R:SetResultTx : SetResult T "x" Int = T -- corresponds to the SetResult type family instance 
    2929}}} 
    3030 
    3131== The naming of cats == 
    3232 
    33 The `AvailTC Name [Name] [(OccName, Name)]` constructor of `AvailInfo` represents a type and its pieces that are in scope. Record fields are now stored in a separate list (the third argument), along with their selectors. The `IEThingWith name [name] [OccName]` constructor of `IE`, which represents a thing that can be imported or exported, only stores the field labels. '''SLPJ''' Whoa!  Why should we duplicate this info.  My gut feel is that the selector should not appear in the second argument. '''AMG''' Does this sound better now? It's helpful if `gresFromAvail` need not do lookups (it is called by the desugarer). 
    34  
    35 The `Parent` type has an extra constructor `FldParent Name OccName` that stores the parent `Name` and the field `OccName`. The `GlobalRdrElt` (`GRE`) for a field stores the selector name directly, and uses the `FldParent` constructor to store the field. Thus a field `foo` of type `T` gives rise this entry in the `GlobalRdrEnv`: 
    36  
    37 {{{ 
    38 foo |->  GRE $sel_foo_T (FldParent T foo) LocalDef 
    39 }}} 
    40  
    41 '''SLPJ''' moreover I think we should store the ''dictionary'' `$dfHasTfoo` in the GRE for `foo`, not the selector.  That way we get both getter and setter (via the dictionary) in one go.  '''AMG''' Now I'm not sure about this. We can't build the dictionary for higher-rank fields, but they have a perfectly good selector. Moreover, with type-changing update there are two dictionaries (one for the getter and one for the setter) and two coercion axioms. 
     33A field is represented by the following datatype, parameterised by the representation of names: 
     34 
     35{{{ 
     36data FieldLbl a = FieldLabel { 
     37      flOccName   :: OccName,           -- ^ Label of the field 
     38      flSelector  :: a,                 -- ^ Record selector function 
     39      flInstances :: Maybe (FldInsts a) -- ^ Instances for overloading 
     40    } 
     41 
     42type FieldLabel = FieldLbl Name 
     43 
     44data FldInsts a = FldInsts { fldInstsHas :: a 
     45                           , fldInstsUpd :: a 
     46                           , fldInstsGetResult :: a 
     47                           , fldInstsSetResult :: a } 
     48}}} 
     49 
     50Every field has a label (`OccName`) and selector. If it is defined in a module with `-XOverloadedRecordFields` enabled, it also has names for the instances.  
     51 
     52The `AvailTC Name [Name] [FieldLabel]` constructor of `AvailInfo` represents a type and its pieces that are in scope. Record fields are now stored in a separate list (the third argument). The `IEThingWith name [name] [OccName]` constructor of `IE`, which represents a thing that can be imported or exported, stores only the `OccName`s. 
     53 
     54The `Parent` type has an extra constructor `FldParent Name OccName (Maybe (FldInsts Name))` that stores the parent `Name`, the field `OccName`, and the names of the instances if they are defined. The `GlobalRdrElt` (`GRE`) for a field stores the selector name directly, and uses the `FldParent` constructor to store the field. Thus a field `x` of type `T` gives rise this entry in the `GlobalRdrEnv`: 
     55 
     56{{{ 
     57x |->  GRE $sel_x_T (FldParent T x (Just (FldInsts $dfHasTx $dfUpdTx TFCo:R:GetResultTx TFCo:R:SetResultTx))) LocalDef 
     58}}} 
    4259 
    4360Note that the `OccName` used when adding a GRE to the environment (`greOccName`) now depends on the parent field: for `FldParent` it is the field label rather than the selector name. 
    4461 
    45 The `dcFields` field of `DataCon` stores a list of `FieldLabel`, defined thus: 
    46  
    47 {{{ 
    48 type FieldLbl a = FieldLabel { 
    49                       flOccName  :: OccName, -- ^ Label of the field 
    50                       flSelector :: a        -- ^ Record selector function 
    51                   } 
    52 type FieldLabel = FieldLbl Name 
    53 }}} 
    54  
    55 whereas the `ifConFields` field of `IfaceConDecl` stores a list of `FieldLbl OccName`. 
     62The `dcFields` field of `DataCon` stores a list of `FieldLabel`, whereas the `ifConFields` field of `IfaceConDecl` stores a list of `FieldLbl OccName`. 
    5663 
    5764 
     
    1081152. Otherwise, all the instances must be generated, as if the field were locally defined. 
    109116 
     117'''AMG''' Modules in `base` that are compiled before `GHC.Records` cannot have the instances created. This is the motivation for restricting dfun and family instance generation to modules with the extension enabled. It occurs to me that we could have a separate extension for generating the instances (`-XOverloadedRecordFieldInstances`, perhaps) that could be enabled by default (except for `base`). This would reduce the number of fields for which `-XOverloadedRecordFields` modules would have to generate instances on the fly. On the other hand, it would increase the amount of stuff in interface files. 
     118 
    110119 
    111120== Unused imports == 
     
    267276* Consider defaulting `Accessor p` to `p = (->)`, and defaulting `Has r "f" t` constraints where there is only one datatype with a field `f` in scope. 
    268277* Sort out reporting of unused imports. 
    269 * How should dfunids/axioms and instances be propagated? 
     278* Review propagation of dfunids/axioms and instances; consider `-XOverloadedRecordFieldInstances` as a separate extension. 
    270279* How should instances be made available to GHCi? 
    271280* Document the extension, including new warnings.