Changes between Version 13 and Version 14 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 26, 2012 2:04:07 AM (2 years ago)
Author:
AntC
Comment:

Add example of changing record type (parametric)

Legend:

Unmodified
Added
Removed
Modified
  • Records/TypePunningDeclaredOverloadedRecordFields

    v13 v14  
    123123'''Technical capabilities''' and limitations for the `Has` class: 
    124124 * Monomorphic fields can be `get` and `set`. 
    125  * Parametric polymorphic fields can be applied in polymorphic contexts, and can be `set` including changing the type of the record.[[BR]](This uses the `SetResult` type function.)[[BR]]To do: provide example with desugarring. 
     125 * Parametric polymorphic fields can be applied in polymorphic contexts, and can be `set` including changing the type of the record.[[BR]](This uses the `SetResult` type function. See example below.) 
    126126 * Multiple fields can be updated in a single expression (using familiar H98 syntax), but this desugars to nested updates, which is inefficient. 
    127127 * Pattern matching and record creation using the data constructor prefixed to { ... } work as per H98 (using `DisambiguateRecordFields` and friends). 
     
    129129 * 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: 
    130130 
     131 
     132'''Higher-Ranked polymorphic fields''' (including class-constrained polymorphism) 
    131133{{{ 
    132     data HR = HR { rev :: (forall a. [a] -> [a]) }                      -- would generate: 
    133  
    134     type instance SetResult HR t  = HR                                  -- HR is not parametric 
     134 -- data HR = HR { rev :: (forall a. [a] -> [a]) }                      -- _not_ sharing, so would generate: 
    135135 
    136136    newtype Rev = Rev (forall a. [a] -> [a]) 
     137    data HR = HR { rev :: Rev } 
     138 
    137139    rev :: HR -> (forall a. [a] -> [a])                                 -- generated selector is monomorphic in HR, 
    138140                                                                        --         'cos not sharing 
     
    145147 
    146148    type instance GetResult r Rev     = Rev 
    147  
     149    type instance SetResult HR t      = HR                              -- HR is not parametric 
    148150 
    149151}}} 
     
    151153 * Now we can now apply the wrapped function polymorphically (after unwrapping within the user code). 
    152154 
     155'''Parametric polymoprhic fields''' (including changing the parametric record type) 
     156{{{ 
     157 -- data ParamR a = ParamR { paramA :: a }                              -- _not_ sharing, so would generate: 
     158 
     159    newtype ParamA a = ParamA a 
     160    data ParamR a = ParamR { paramA :: ParamA a } 
     161 
     162    paramA :: ParamR a -> a                                             -- generated selector is monomorphic in ParamR, 
     163    paramA r = get r (undefined :: ParamA a) 
     164 
     165    instance Has (ParamR a) (ParamA _a)        where                    -- Note: different type args 
     166        get ParamR{ paramA = ParamA x } = x                             -- unwrap the value from the newtype 
     167        set (ParamA x) ParamR{ .. }     = ParamR{ paramA = ParamA x, .. } 
     168 
     169    type instance GetResult (ParamR a) (ParamA _a)  = a                  -- take param type as is (_a is dummy) 
     170    type instance SetResult (ParamR _a) (ParamA a)  = ParamR a           -- take param type to be (_a is dummy) 
     171 
     172}}} 
    153173 
    154174.