[Haskell-cafe] record update

Wolfgang Jeltsch g9ks157k at acme.softbase.org
Mon Sep 13 08:24:30 EDT 2010


Am Samstag, den 11.09.2010, 11:21 -0600 schrieb Jonathan Geddes:
> I know that record updates is a topic that has become a bit of a dead
> horse, but here I go anyway:
> 
> I find that most of the record updates I read and write take the form
> 
> >someUpdate :: MyRecord -> MyRecord
> >someUpdate myRecord = myRecord
> >     { field1 = f $ field1 myRecord
> >     , field2 = g $ field2 myRecord
> >     , field3 = h $ filed3 myRecord
> >     }
> 
> I find myself wishing I could write something more like
> 
> >someUpdate :: MyRecord -> MyRecord
> >someUpdate myRecord = myRecord
> >     { field1 => f
> >     , field2 => g
> >     , field3 => h
> >     }
> 
> with equivalent semantics. Here => reads "is transformed by". Operator
> = could still be used for assignment as in current record updates.
> 
> The best part about such an extension, in my opinion, is that it would
> open the door for anonymous lambda record updates. Something like:
> 
> >someUpdate :: MyRecord -> MyRecord
> >someUpdate = \{field1 => f, field2 => g, field3 => h}
> 
> again, with the same semantics. This becomes possible because you no
> longer need to refer to the record within the {} part of the update.
> 
> This would be useful, for example, in the State monad. We could write:
> 
> >someStateTransform :: State MyRecord ()
> >someStateTransform = do
> >     modify $ \{field1 => (++"!")}
> >     ...
> 
> where currently we see code like
> 
> >someStateTransform :: State MyRecord ()
> >someStateTransform = do
> >     modify $ \record->record{field1 = (++"!") $ field1 record}
> >     ...
> 
> which repeats the record name 3 times and the field name twice. The
> repetition just feels out of place next to all the other terse,
> readable Haskell code in the program.
> 
> So what do my fellow haskellers think? Is this idea worth writing up a
> proposal for?
> 
> Alternatively, can you offer me some advice on writing code in Haskell
> 2010 that avoids the ugly, repetitive style of record update?
> 
> --Jonathan

You might want to have a look at the records package:

    <http://hackage.haskell.org/package/records>

Here is a code example:

> import Data.Kind
> import Data.TypeFun
> import Data.Record
> import Data.Record.Combinators
>
> data Surname = Surname deriving (Show)
> data Age     = Age     deriving (Show)
> data Room    = Room    deriving (Show)
>
> instance Name Surname where name = Surname
> instance Name Age     where name = Age
> instance Name Room    where name = Room
>
> oldData = X :& Surname := "Jeltsch"
>             :& Age     := 31
>             :& Room    := "EH/202"
>             `withStyle` Id KindStar
>
> newData = modify (X :& Age := (+2) :& Room := const "HG/2.39") oldData

Evaluating newData gives you:

> X :& Surname := "Jeltsch" :& Age := 33 :& Room := "HG/2.39"

If you have any question regarding the records package, please ask,
since I’m its author. :-) 

Best wishes,
Wolfgang



More information about the Haskell-Cafe mailing list