Changes between Version 20 and Version 21 of Records/OverloadedRecordFields/Plan


Ignore:
Timestamp:
Jul 17, 2013 3:30:46 PM (9 months ago)
Author:
adamgundry
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records/OverloadedRecordFields/Plan

    v20 v21  
    7979=== Representation hiding === 
    8080 
    81 At present, a datatype in one module can declare a field, but if the selector function is not exported, then the field is hidden from clients of the module. It is important to support this. Typeclasses in general have no controls over their scope, but for implicitly generated `Has` instances, the instance is available for a module if `-XOverloadedRecordFields` is enabled for that module and the record field selector function is in scope. 
     81At present, a datatype in one module can declare a field, but if the selector function is not exported, then the field is hidden from clients of the module. It is important to support this. Typeclasses in general have no controls over their scope, but for implicitly generated `Get` instances, the instance is available for a module if `-XOverloadedRecordFields` is enabled for that module and the record field selector function is in scope. Instances are generated on the client side, rather than being exported from the defining module. 
    8282 
    8383This enables representation hiding: just like at present, exporting the field selector permits access to the field. For example, consider the following module: 
     
    9090}}} 
    9191 
    92 Any module that imports `M` will have access to the `x` field from `R` but not from `S`, because the instance `Has R "x" Int` will be available but the instance `Has S "x" Bool` will not be. Thus `R { x :: Int }` will be solved but `S { x :: Bool }` will not. 
     92Any module that imports `M` will have access to the `x` field from `R` but not from `S`, because the instance `Get R "x" Int` will be available but the instance `Get S "x" Bool` will not be. Thus `R { x :: Int }` will be solved but `S { x :: Bool }` will not. 
    9393 
    9494 
    9595=== Multiple modules and automatic instance generation === 
    9696 
    97 Note that `Has` instances are generated on a per-module basis, using the fields that are in scope for that module, and automatically generated instances are never exported. Thus it doesn't matter whether `-XOverloadedRecordFields` was on in the module that defined the datatype. The availability of the instances in a particular module depends only on whether the flag is enabled for that module. 
    98  
    99 Suppose module `M` imports module `N`, `N` imports module `O`, and only `N` has the extension enabled. Now `N` can project any field in scope (including those defined in `O`), but `M` cannot access any `Has` instances.  
     97Note that `Get` instances are generated on a per-module basis, using the fields that are in scope for that module, and automatically generated instances are never exported. Thus it doesn't matter whether `-XOverloadedRecordFields` was on in the module that defined the datatype. The availability of the instances in a particular module depends only on whether the flag is enabled for that module. 
     98 
     99Suppose module `M` imports module `N`, `N` imports module `O`, and only `N` has the extension enabled. Now `N` can project any field in scope (including those defined in `O`), but `M` cannot access any `Get` instances.  
    100100 
    101101This means that 
    102  * the extension is required whenever a `Has` constraint must be solved; 
     102 * the extension is required whenever a `Get` constraint must be solved; 
    103103 * no new mechanism for hiding instances is required; and 
    104104 * records defined in existing modules (or other packages) without the extension can still be overloaded. 
     
    107107=== Higher-rank fields === 
    108108 
    109 If a field has a rank-1 type, the `Has` encoding works fine: for example, 
     109Higher-rank fields, such as 
    110110 
    111111{{{ 
     
    113113}}} 
    114114 
    115 gives rise to the instance 
    116  
    117 {{{ 
    118 instance (b ~ a -> a) => Has T "x" b 
    119 }}} 
    120  
    121 However, if a field has a rank-2 type or higher (so the selector function has rank at least 3), things are looking dangerously impredicative: 
    122  
    123 {{{ 
    124 data T b = MkT { x :: (forall a . a -> a) -> b } 
    125 }}} 
    126  
    127 would give 
    128  
    129 {{{ 
    130 instance (c ~ ((forall a . a -> a) -> b)) => Has (T b) "x" c 
    131 }}} 
    132  
    133 but this is currently forbidden by GHC, even with `-XImpredicativeTypes` enabled. Indeed, it would not be much use if it were possible, because bidirectional type inference relies on being able to immediately infer the type of neutral terms like `x e`, but overloaded record fields prevent this. Non-overloaded field names are likely to be needed in this case.  
     115cannot be overloaded. If such a field is declared in a module with `-XOverloadedRecordFields` enabled, a warning will be emitted and no selector produced. The user can always declare the selector function manually. 
     116 
     117Bidirectional type inference for higher-rank types relies on inferring the type of functions, so that types can be pushed in to the arguments. However, the type of an overloaded field cannot immediately be inferred (as some constraint solving is required). This is why higher-rank and overloaded fields are incompatible. 
     118 
     119Some previous variants of the design supported rank-1 universally quantified fields (but not rank-2 and above). However, these prevent the third parameter of the `Get` class from being a function of the first two, and hence obstruct type inference for compositions of selectors. 
    134120 
    135121 
     
    141127 * records may include higher-rank components. 
    142128 
    143 These problems have already been [wiki:Records/OverloadedRecordFields#Recordupdates described in some detail]. In the interests of doing something, even if imperfect, we plan to support only monomorphic record update. For overloaded fields to be updated, a type signature may be required in order to specify the type being updated. For example, 
     129These problems have already been [wiki:Records/OverloadedRecordFields#Recordupdates described in some detail]. In the interests of doing something, even if imperfect, the Haskell 98 record update syntax will support only monomorphic update. For overloaded fields to be updated, a type signature may be required in order to specify the type being updated. For example, 
    144130{{{ 
    145131e { x = t }