Changes between Version 3 and Version 4 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 12, 2012 3:26:27 AM (5 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: