Typos in my last message: the identifier "field" should be "Field" throughout, 
and "undef" should be "undefined". Here is the corrected version:

Nonextensible records with polymorphic selectors.
=================================================

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 automatically an instance of Label, and you can't define other 
instances.

2. Define a class (in a library somewhere)

        class Label n => Contains r n where
                type Field r n :: *
                select :: r -> n -> Field r n
                update :: r -> n -> Field r n -> r

3. Declarations with field labels such as

        data C = F {l1 :: t1, l2 :: t2} | G {l2 :: t2}

are syntactic sugar for

        data C = F t1 t2 | G t2

        instance Contains C ''l1'' where
                Field C ''l1'' = t1
                select (F x y) _ = x
                update (F x y) _ x' = F x' y

        instance Contains C ''l2'' where
                Field C ''l2'' = t2
                select (F x y) _ = y
                select (G y) _ = y
                update (F x y) _ y' = F x y'
                update (G y) _ y' = G y'

4. Selector functions only need to be defined once, however many types they are 
used in

        l1 :: Contains r ''l1'' => r -> Field r ''l1''
        l1 = select r (undefined ::''l1'')

        l2 :: Contains r ''l2'' => r -> Field r ''l2''
        l2 = select r (undefined ::''l2'')

5. Constructors are exactly as before

6. Updates such as

        r {l1 = x}

are syntactic sugar for

        update r (undefined::''l1'') x

=====================================================

Sorry about that.

Barney.


_______________________________________________
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users

Reply via email to