Changes between Version 7 and Version 8 of Records/OverloadedRecordFields/Design


Ignore:
Timestamp:
Apr 22, 2014 10:27:27 AM (13 months ago)
Author:
simonpj
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Design

    v7 v8  
    184184=== Limited type-changing update === 
    185185 
    186 As noted above, supporting a polymorphic version of the existing record update syntax (in its full generality) is difficult. However, we can generate instances of the following class and type family, which permit type-changing update of single fields: 
     186As noted above, supporting a polymorphic version of the existing record update syntax (in its full generality) is difficult. However, we do generate instances of the class `Upd` and type family `UpdTy`, which permit type-changing update of single fields: 
    187187 
    188188{{{ 
    189189type family UpdTy (r :: *) (n:: Symbol) (a :: *) :: * 
    190190 
    191 class (Has r n (FldTy r n), r ~ UpdTy r n (FldTy r n)) => 
    192          Upd (r :: *) (n :: Symbol) (t :: *) where 
     191class (Has r n (FldTy r n), r ~ UpdTy r n (FldTy r n)) 
     192   => Upd (r :: *) (n :: Symbol) (t :: *) where 
    193193  setField :: Proxy# n -> r -> t -> UpdTy r n t 
    194194}}} 
     
    298298}}} 
    299299 
    300 An instance of `Accessor p r n t` means that `p` may contain a getter and setter for the field `n` of type `t` in record type `r`. In particular, we can give an instance for functions that ignores the setter completely: 
     300An instance of `Accessor p r n t` means that `p` may contain a getter and setter for the field `n` of type `t` in record type `r`. In particular, we can give the following instance for function arrow, that ignores the setter completely: 
    301301 
    302302{{{ 
     
    304304  accessor _ getter setter = getter 
    305305}}} 
    306  
    307 Thus, whenever a field `foo` is used at a function type (by applying it or composing it, for example), this instance will be selected. That is, `foo` translates to `field proxy#`, which computes to `accessor proxy# (getField proxy#) (setField proxy#)`, and hence to `getField proxy#` by the `Accessor` instance for functions. 
    308  
    309 However, `p` does not have to be the function arrow. Suppose the `lens` library defined the following newtype wrapper: 
     306So, if the source program contains `foo r` (meaning "select field `foo` from record `r`), it will be interpreted like this, if `r :: T`: 
     307{{{ 
     308                     foo r 
     309desugaring      ==> field (proxy# :: Proxy# "foo") r 
     310inline 'field'  ==> accessField (proxy# :: Proxy# "foo") 
     311                                (getField (proxy# :: Proxy# "foo")) 
     312                                (setField (proxy# :: Proxy# "foo")) 
     313                                r 
     314(->) instance   ==> getField (proxy# :: Proxy# "foo") r 
     315of Accessor 
     316 
     317"foo" instance  => sel_T_foo r     -- Select the foo field in the T type 
     318of Has 
     319}}} 
     320Of course the field doesn't have to by syntactically applied; the above will happen whenever it is used as a function. 
     321 
     322However, with this additional generality, the field does not have to be used as a function!  (Or, to put it another way, `p` does not have to be the function arrow.) Suppose the `lens` library defined the following newtype wrapper: 
    310323 
    311324{{{