Changes between Version 8 and Version 9 of Records


Ignore:
Timestamp:
Sep 16, 2011 11:06:06 AM (3 years ago)
Author:
barney
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Records

    v8 v9  
    3535 1. Better name spacing 
    3636 2. Type directed name resolution 
     37 3. Nonextensible records with polymorphic selection & update 
    3738 
    3839'''Are there any other approaches?''' 
     
    6061One 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.) 
    6162 
     63--------------------------- 
     64=== Nonextensible records with polymorphic selection & update === 
     65 
     66The 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: 
     67 
     681. 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{{{ 
     70data ''string'' 
     71 
     72instance Label ''string'' 
     73}}} 
     74This has global scope, so `''string''` is the same type in all modules. You can't define other instances of `Label`. 
     75 
     762. Define a class (in a library somewhere) 
     77{{{ 
     78class 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}}} 
     833. Declarations with field labels such as 
     84{{{ 
     85data C = F {l1 :: t1, l2 :: t2} | G {l2 :: t2} 
     86}}} 
     87are syntactic sugar for 
     88{{{ 
     89data C = F t1 t2 | G t2 
     90 
     91instance 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 
     96instance 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}}} 
     1034. Selector functions only need to be defined once, however many types they are used in 
     104{{{ 
     105l1 :: Contains r ''l1'' => r -> Field r ''l1'' 
     106l1 = select r (undefined ::''l1'') 
     107 
     108l2 :: Contains r ''l2'' => r -> Field r ''l2'' 
     109l2 = select r (undefined ::''l2'') 
     110}}} 
     1115. Constructors are exactly as they are currently. I can't see any use for polymorphic constructors when records are nonextensible. 
     112 
     1136. Updates such as 
     114{{{ 
     115r {l1 = x} 
     116}}} 
     117are syntactic sugar for 
     118{{{ 
     119update r (undefined::''l1'') x 
     120}}}