[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