Changes between Version 8 and Version 9 of Records


Ignore:
Timestamp:
Sep 16, 2011 11:06:06 AM (4 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}}}