Changes between Version 6 and Version 7 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 12, 2012 4:12:31 AM (3 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.