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


Ignore:
Timestamp:
Apr 22, 2014 10:27:27 AM (17 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{{{