Changes between Version 21 and Version 22 of Records/DeclaredOverloadedRecordFields


Ignore:
Timestamp:
Mar 8, 2012 7:24:32 AM (3 years ago)
Author:
AntC
Comment:

Add thumbnail sketch, by popular demand

Legend:

Unmodified
Added
Removed
Modified
  • Records/DeclaredOverloadedRecordFields

    v21 v22  
    11= Declared Overloaded Record Fields (DORF) =
     2
     3== Thumbnal Sketch ==
     4
     5This 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 record field name is overloaded so that:
     6 * Many record types can be declared in the same module to share the field name.
     7 * The field name can be exported so that records in other modules can share it.
     8The export/import is under usual H98 namespace and module/qualification control, so that when exporting a record type:
     9 * Some fields can be both read and updated;
     10 * Some can be read-only;
     11 * Some can be completely hidden.
     12
     13This proposal introduces several new elements of syntax, all of which desugar to use well-established extensions to ghc. The approach has been proptotyped in ghc v 7.2.1. In particular:
     14 * The field name overloading is implemented through usual class and instance mechanisms.
     15 * Field selectors are ordinary functions named for the field (but overloaded rather than H98's monomorphic), so field selection is regular function application.
     16
     17=== Implementation: the `Has` class, and methods `get` and `set` ===
     18
     19Record declarations, instead of generating a (monomorphic) selector function named for the field, generate a `Has` instance for each record type/field combination. A data declaration, its `Has` instance, and examples of use:
     20{{{
     21    data Customer = Cust{ customer_id :: Int, ... }
     22    instance (t ~ Int) => Has Customer Proxy_customer_id t        where
     23        get Cust{ customer_id } _ = customer_id                         -- DisambiguateRecordFields style
     24        set _ x Cust{ .. }        = Cust{ customer_id = x, .. }         -- RecordWildCards and NamedFieldPuns
     25
     26    myCust :: Customer
     27    ... (customer_id myCust) ...                                        -- field selection is func apply
     28    ... myCust{ customer_id = 27 }                                      -- polymorphic record update
     29}}}
     30
     31Note that the mechanism uses a Proxy as the type 'peg' for a field (this is the wildcard argument to `get` and `set`):
     32 * The Proxy must be declared once, and is then under regular name control.
     33 * The field selector function also must be declared once, using the Proxy.
     34
     35{{{
     36    data Proxy_customer_id                                              -- phantom
     37    customer_id :: r{ customer_id :: Int }
     38    customer_id r = get r (undefined :: Proxy_customer_id)
     39
     40    set Proxy_customer_id 27 myCust
     41}}}
     42 * The field selector function is an (overloaded) call to the `get` function, it's type is a function from a record to
     43
     44
    245
    346