[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)
resp.
> 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.)
Ben
More information about the Haskell
mailing list