Changes between Version 27 and Version 28 of Records/DeclaredOverloadedRecordFields
- Timestamp:
- 03/08/12 01:30:34 (15 months ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Records/DeclaredOverloadedRecordFields
v27 v28 3 3 == Thumbnail Sketch == 4 4 5 This proposal is addressing the narrow issue of '''namespacing for record field names''' by allowing more than one record in the same module to share a field name. Specifically the recordfield name is overloaded so that:5 This proposal is addressing the narrow issue of '''namespacing for record field names''' by allowing more than one record in the same module to share a field name. Specifically each field name is overloaded so that: 6 6 * __Within the same module__, many record types can be declared to share the field name. 7 7 * The field name can be exported so that records __in other modules__ can share it. … … 9 9 10 10 The export/import is under usual H98 namespace and module/qualification control, so that for the record type in an importing module: 11 * Some fields are both `get`able and `set`able;11 * Some fields are both readable and updatable; 12 12 * Some are read-only; 13 13 * Some are completely hidden. … … 19 19 * Field selectors are ordinary functions named for the field (but overloaded rather than H98's monomorphic), so field selection is regular function application. (There is no need for syntactically-based disambiguation at point of use.) 20 20 21 === Implementation: the `Has` class, andmethods `get` and `set` ===22 23 Record declarations generate a `Has` instance for each record type/field combination. As well as type arguments for the record and field, there is a third argument for the field's type, which is set at the instance level using equality constraints in a functional-dependencies style. Here is the `Has` class (`r` is the record, `fld` is the proxy type for the field, `t` is the fields type), an exampledeclaration, its `Has` instance, and examples of use:21 === Implementation: the `Has` class, with methods `get` and `set` === 22 23 Record declarations generate a `Has` instance for each record type/field combination. As well as type arguments for the record and field, there is a third argument for the field's resulting type. This is set at the instance level using equality constraints in a functional-dependencies style. Here is the `Has` class (`r` is the record, `fld` is the proxy type for the field, `t` is the fields type), with an example record declaration, its `Has` instance, and examples of use: 24 24 {{{ 25 25 class Has r fld t where … … 28 28 29 29 data Customer = Cust{ customer_id :: Int, ... } -- declaration syntax same as H98 30 30 31 instance (t ~ Int) => Has Customer Proxy_customer_id t where -- Has instance generated, with ~ constraint 31 32 get Cust{ customer_id } _ = customer_id -- DisambiguateRecordFields pattern … … 34 35 myCust :: Customer -- usual record decl 35 36 ... myCust{ customer_id = 27 } -- polymorphic record update 36 ... (customer_id myCust) ... -- field selection is func apply 37 ... (customer_id myCust) ... -- field selection is func apply, or: 37 38 ... myCust.customer_id ... -- dot notation is sugar for reverse func apply 38 39 }}} … … 40 41 Note that the''' `Has` mechanism''' uses a Proxy as the type 'peg' for a field (this is the wildcard argument to `get` and `set`): 41 42 * The Proxy must be declared once, and is then under regular name control. 42 * The field selector function also must be declared once, using the Proxy.43 44 {{{ 45 -- fieldLabel customer_id :: r -> Int -- new declaration, desugars to Proxy and func43 * The field selector function also must be declared once, defined using the Proxy. 44 45 {{{ 46 fieldLabel customer_id :: r -> Int -- new declaration, desugars to Proxy and func: 46 47 data Proxy_customer_id -- phantom 47 48 customer_id :: r{ customer_id :: Int } => r -> Int -- r{ ... } is sugar for Has constraint … … 66 67 * `Has` uses type family functions to manage type-changing update, which adds complexity -- see Implementer's view. 67 68 * Multiple fields can be updated in a single expression (using familiar H98 syntax), but this desugars to nested updates, which is inefficient. 68 * Pattern matching and record creation using data constructor prefixto { ... } work as per H98 (using DisambiguateRecordFields and friends).69 * Pattern matching and record creation using the data constructor prefixed to { ... } work as per H98 (using DisambiguateRecordFields and friends). 69 70 70 71 .
