Changes between Version 13 and Version 14 of Records


Ignore:
Timestamp:
Nov 5, 2011 10:18:05 PM (4 years ago)
Author:
simonpj
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records

    v13 v14  
    6161One particular way of integrating this idea into Haskell is called [http://hackage.haskell.org/trac/haskell-prime/wiki/TypeDirectedNameResolution Type Directed Name Resolution] (TDNR).  Proposed a couple of years ago, the Haskell community didn't like it much.  (But I still do; SLPJ.)
    6262
    63 ---------------------------
    64 === Nonextensible records with polymorphic selection & update ===
    6563
    66 The ideas in "first class record types" still work in the case of nonextensible records. Using a simplified version of Labels #2104 we can implement truly polymorphic selection and update, which would be more expressive than TDNR and wouldn't need a whole new type resolution mechanism.  Here is a concrete proposal (Barney Hilken); see also [wiki:Records/OverloadedRecordFields]:
    67 
    68 1. Introduce a built-in class `Label`, whose members are strings at the type level. We need a notation for them; I will use double single quotes, so `''string''` is treated as if it was defined by
    69 {{{
    70 data ''string''
    71 
    72 instance Label ''string''
    73 }}}
    74 This has global scope, so `''string''` is the same type in all modules. You can't define other instances of `Label`.
    75 
    76 2. Define a class (in a library somewhere)
    77 {{{
    78 class Label n => Contains r n where
    79         type Field r n :: *
    80         select :: r -> n -> Field r n
    81         update :: r -> n -> Field r n -> r
    82 }}}
    83 3. Declarations with field labels such as
    84 {{{
    85 data C = F {l1 :: t1, l2 :: t2} | G {l2 :: t2}
    86 }}}
    87 are syntactic sugar for
    88 {{{
    89 data C = F t1 t2 | G t2
    90 
    91 instance Contains C ''l1'' where
    92         Field C ''l1'' = t1
    93         select (F x y) _ = x
    94         update (F x y) _ x' = F x' y
    95 
    96 instance Contains C ''l2'' where
    97         Field C ''l2'' = t2
    98         select (F x y) _ = y
    99         select (G y) _ = y
    100         update (F x y) _ y' = F x y'
    101         update (G y) _ y' = G y'
    102 }}}
    103 4. Selector functions only need to be defined once, however many types they are used in
    104 {{{
    105 l1 :: Contains r ''l1'' => r -> Field r ''l1''
    106 l1 = select r (undefined ::''l1'')
    107 
    108 l2 :: Contains r ''l2'' => r -> Field r ''l2''
    109 l2 = select r (undefined ::''l2'')
    110 }}}
    111 5. Constructors are exactly as they are currently. I can't see any use for polymorphic constructors when records are nonextensible.
    112 
    113 6. Updates such as
    114 {{{
    115 r {l1 = x}
    116 }}}
    117 are syntactic sugar for
    118 {{{
    119 update r (undefined::''l1'') x
    120 }}}