Changes between Version 6 and Version 7 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 12, 2012 4:12:31 AM (2 years ago)
Author:
AntC
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/TypePunningDeclaredOverloadedRecordFields

    v6 v7  
    4444{{{ 
    4545    class Has r t                                           where 
    46         get :: r -> t -> GetResult r t                                  -- see instances below 
     46        get :: r -> t -> GetResult r t                                  -- see type instances below 
    4747        set :: t -> r -> SetResult r t                                  -- use where changing the record's type 
    4848 
     
    6868    instance Has Customer FirstName                         where       -- Has instance generated 
    6969        get Customer{ firstName = (FirstName x) } = x                   -- DisambiguateRecordFields pattern 
    70         set x Customer{ .. }    = Customer{ firstName = (FirstName x), .. }   -- RecordWildCards and NamedFieldPuns 
     70        set x Customer{ .. }    = Customer{ firstName = x, .. }         -- RecordWildCards and NamedFieldPuns 
    7171 
    7272    type instance GetResult Customer FirstName     = String             -- specific to this record/field 
     
    7575 
    7676    myCust :: Customer                                                  -- usual record decl 
    77     ... myCust{ customer_id = 27, firstName = Fred }                    -- **polymorphic** record update, no data constr 
     77    ... myCust{ customer_id = 27, firstName = "Fred" }                  -- **polymorphic** record update, no data constr 
    7878    ... (customer_id myCust) ...                                        -- field selection is func apply, or: 
    7979    ... myCust.customer_id ...                                          -- dot notation is sugar for reverse func apply 
     
    8383 * Each field must be a distinct type. 
    8484 * 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 to share.) 
     85 * The type functions are not associated types, because: 
     86    * GetResult for shared fields depends only on the Field's type (per Customer_id above); 
     87    * SetResult for non-parametric record types does not change the record type. 
    8588 * The field selector function also must be declared once, defined punning on the field's type.[[BR]](See below for syntactic sugar to declare these.) 
    8689 
     
    9194    newtype Customer_id = Customer_id Int                               -- newtype or data decl, same name type and constr 
    9295                                           deriving (Has, ...)          -- generates customer_id function, per above 
     96 
     97    data Customer = Customer { :: Customer_id, ... }                    -- auto-gen field label pun on type name 
     98                             sharing (Customer_id, ...) 
    9399}}} 
    94100 
    95 Polymorphic record updates: 
     101Polymorphic record updates, alternative syntax (note, no data constructor for the record): 
    96102{{{ 
    97103    set (Customer_id 27) (                                              -- record update desugarred from above example 
    98104               set (FirstName "Fred") myCust  )                         -- note nested 
    99105 
    100     ... myCust{ cust_id, FirstName "Fred" }                             -- equiv syntax (assuming cust_id :: Customer_id) 
     106    ... myCust{ cust_id, FirstName "Fred" }                             -- equiv syntax **only** for polymorphic updates 
     107                                                                        -- (assuming cust_id :: Customer_id) 
    101108}}} 
    102109 
     
    116123 * Multiple fields can be updated in a single expression (using familiar H98 syntax), but this desugars to nested updates, which is inefficient. 
    117124 * Pattern matching and record creation using the data constructor prefixed to { ... } work as per H98 (using `DisambiguateRecordFields` and friends). 
    118  * Higher-ranked polymorphic fields (including class-constrained) can be applied in polymorphic contexts, and can be set -- __providing__ they are wrapped in a newtype. 
     125 * Higher-ranked polymorphic fields (including class-constrained) can be applied in polymorphic contexts, and can be set -- __providing__ they are wrapped in a newtype. Here is SPJ's example: 
     126 
     127{{{ 
     128    newtype Rev = Rev (forall a. [a] -> [a])        deriving (Has) 
     129    newtype OrdRev = OrdRev (Ord a => [a] -> [a])   deriving (Has) 
     130 
     131    data HR = HR{ rev :: Rev, ordRev :: OrdRev } sharing (Rev, OrdRev) 
     132}}} 
     133 * Note that to get/set those h-r fields needs them to be un/wrapped within the user code. 
    119134 
    120135.