Changes between Version 11 and Version 12 of Records/TypePunningDeclaredOverloadedRecordFields
- Timestamp:
- 03/25/12 15:22:00 (14 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Records/TypePunningDeclaredOverloadedRecordFields
v11 v12 86 86 * 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.) 87 87 * The type functions are not associated types, because: 88 * `GetResult` for shared fields depends only on the Field's type (per Customer_idabove);88 * `GetResult` for shared fields depends only on the Field's type (per `Customer_id` above); 89 89 * `SetResult` for non-parametric record types continues the same record type. 90 90 * 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.) … … 123 123 '''Technical capabilities''' and limitations for the `Has` class: 124 124 * 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 SetResulttype 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.)[[BR]]To do: provide example with desugarring. 126 126 * Multiple fields can be updated in a single expression (using familiar H98 syntax), but this desugars to nested updates, which is inefficient. 127 127 * Pattern matching and record creation using the data constructor prefixed to { ... } work as per H98 (using `DisambiguateRecordFields` and friends). … … 135 135 136 136 newtype Rev = Rev (forall a. [a] -> [a]) 137 rev :: HR -> Rev -> (forall a. [a] -> [a]) -- generated selector is monomorphic138 rev r = get r (undefined :: Rev)137 rev :: HR -> Rev -> (forall a. [a] -> [a]) -- generated selector is polymorphic 138 rev r = let (Rev fn) = get r (undefined :: Rev) in fn -- unwrap from the newtype 139 139 140 140 instance Has HR Rev where -- Has instance generated 141 get HR{ rev = (Rev x) } = x -- looks OK, but see GetResult142 set x HR{ .. } = HR{ rev = x, .. }-- note x is already wrapped141 get HR{ rev = (Rev x) } = Rev x -- can't unwrap here, 'cos can't spec Poly 142 set (Rev x) HR{ .. } = HR{ rev = Rev x, .. } -- note x is already wrapped 143 143 144 type instance GetResult HR Rev = (forall a. [a] -> [a]) -- no can do! not allowed forall's on RHS 145 -- (and can't do equality constraints on type instances) 146 {- ??can we do better -- perhaps an eq constraint on the Has instance: 147 (GetResult HR Rev ~ ([a] -> [a])) => Has ... 148 plus a non-commital result for getResult 149 -} 144 type instance GetResult r Rev = Rev 150 145 151 {- instead, do explicit newtype wrapping for higher-rank types: -}152 146 153 newtype Rev = Rev (forall a. [a] -> [a]) deriving (Has) 154 newtype OrdRev = OrdRev (Ord a => [a] -> [a]) deriving (Has) -- class constrained 147 }}} 155 148 156 data HRW = HRW{ rev :: Rev, ordRev :: OrdRev } sharing (Rev, OrdRev) 157 }}} 158 * Now we can now apply the wrapped function polymorphically (after unwrapping within the user code. 149 * Now we can now apply the wrapped function polymorphically (after unwrapping within the user code). 159 150 160 151
