[Haskell] Proposal: Allow "\=" for field update in record update syntax

Benjamin Franksen benjamin.franksen at bessy.de
Sat Feb 19 16:33:48 EST 2005

I think that the best solution is to define record labels as types, or rather 
type proxies, like for instance in the HList library. This fixes the most 
important deficiencies of Haskell98 records:

- labels are now first class values
- labels no longer need to be globally unique, but only unique per record
- operations to get or set a field are normal (overloaded) functions (and
  can be given operator aliases, if desired)

This library class defines the operations on a record:

	class RecordField r l t | r l -> t where
	  getField :: l -> r -> t
	  putField :: l -> t -> r -> r

	updateField :: (Field r l t) => l -> (t -> t) -> r -> r
	updateField lbl fun rec = putField lbl (fun $ getField lbl rec) rec

The record declaration

	data R = R {
	    field1 :: T1,
	    field2 :: T2

would be syntactic sugar for

	data R = R T1 T2

	data Label_field1

	field1 :: Label_field1
	field1 = undefined

	instance RecordField R Label_field1 T1 where
	  getField (Rec x _) _ = x
	  putField (Rec _ y) _ v = Rec v x

	-- analogous definitions for field2 left out

Note that the compiler would leave out the definition of Label_field1 and 
field1 if these are already in scope.

Alexanders example

>     fun rec = rec // $(u field1 fn) . $(a field2 val)


>     fun rec = rec // u_field1 fn . a_field2 val

could now be written thus

	fun = updateField field1 fn . putField field2 val

without any need for additional syntax or infix operator splices.

I wonder if something similar could be done with TH. The labels would need to 
have a different name (e.g. l_field1, l_field2), so they don't collide with 
their Haskell98 definitions, but otherwise everything should be as above. I 
am thinking of something like

	$(generateLabels R)

(I am not very familiar with TH, so this could be wrong syntax or otherwise 
impossible to do.)


More information about the Haskell mailing list