Changes between Version 13 and Version 14 of Records/TypePunningDeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 26, 2012 2:04:07 AM (3 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.