Changes between Version 3 and Version 4 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 12, 2012 3:26:27 AM (2 years ago)
Author:
AntC
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/TypePunningDeclaredOverloadedRecordFields

    v3 v4  
    4343Here is the `Has` class with instances for the above Customer record, and examples of use: 
    4444{{{ 
    45     class Has r fld t                                             where 
    46         get :: r -> fld -> t                                            -- simplified form 
    47         set :: fld -> t -> r -> r                                       -- where not changing record's type 
     45    class Has r t                                           where 
     46        get :: r -> t -> GetResult r t                                  -- see instances below 
     47        set :: t -> r -> SetResult r t                                  -- use where changing the record's type 
    4848 
    49     data Customer = Cust{ customer_id :: Int, ... }                     -- declaration syntax same as H98 
     49    type family GetResult r t :: * 
     50    type family SetResult r t :: * 
    5051 
    51     instance (t ~ Int) => Has Customer Proxy_customer_id t        where -- Has instance generated, with ~ constraint 
    52         get Cust{ customer_id } _ = customer_id                         -- DisambiguateRecordFields pattern 
    53         set _ x Cust{ .. }        = Cust{ customer_id = x, .. }         -- RecordWildCards and NamedFieldPuns 
     52    instance Has Customer Customer_id                       where       -- Has instance generated for sharing field 
     53        get Customer{ customer_id } = customer_id                       -- DisambiguateRecordFields pattern 
     54        set x Customer{ .. }        = Customer{ customer_id = x, .. }   -- RecordWildCards and NamedFieldPuns 
     55 
     56    type instance GetResult r Customer_id = Customer_id                 -- same result all record types 
     57    type instance SetResult Customer t    = Customer                    -- record type is not parametric, so doesn't change 
     58 
     59    newtype FirstName = FirstName String                                -- newtype generated for non-sharing field 
     60    instance Has Customer FirstName                         where       -- Has instance generated 
     61        get Customer{ firstName = (FirstName x) } = x                   -- DisambiguateRecordFields pattern 
     62        set x Customer{ .. }    = Customer{ firstName = (FirstName x), .. }   -- RecordWildCards and NamedFieldPuns 
     63 
     64    type instance GetResult Customer FirstName     = String             -- specific to this record/field 
     65    -- type instance SetResult Customer FirstName  = Customer           -- not needed/already declared above 
     66 
     67   customer_id r = get r :: Customer_id                                 -- we can auto-decl this, see below 
    5468 
    5569    myCust :: Customer                                                  -- usual record decl 
     
    5973}}} 
    6074 
    61 Note that the''' `Has` mechanism''' uses a Proxy as the type 'peg' for a field (this is the wildcard argument to `get` and `set`): 
    62  * There must be a Proxy_type declared for each distinct field name. 
    63  * The Proxy must be declared once, and the Proxy is then under regular name control. 
    64  * The field selector function also must be declared once, defined using the Proxy. 
     75Note that the''' `Has` mechanism''' uses '''the field's type itself''' to locate the field within the record: 
     76 * Each field must be a distinct type. 
     77 * The Type must be declared once (within the scope), and is then under regular name control.[[BR]](Probably you're doing this already for critical fields.) 
     78 * The field selector function also must be declared once, defined punning on the field's type. 
    6579 
    66     It is an error to declare a record field without there being a Proxy in scope. The desugar for the data decl would create the instance to use the Proxy, but then the instance would fail. 
     80    It is an error to be `sharing` a record field without there being a same-named type in scope. The desugar for the data decl would create the instance to use the Type, but then the instance would fail. 
    6781 
    6882To generate the correct declarations, there is to be a new `fieldLabel` sugar: