updating labelled fields

Jorge Adriano jadrian@mat.uc.pt
Mon, 6 May 2002 19:36:30 +0100


> I often create structures like:
> data MyData =3D MyData { foo :: ..., bar :: ..., .... }
That makes 2 of us :-)

> and most of the time i do one of two things:
>   1) read values from the structure, as in:
>              let x =3D (foo myData) in ...
>   2) update values in the structure, as in:
>              let myData' =3D myData { foo =3D (foo myData)+1 }

1)=20
I've used datatypes with labeled fields mostly to pass around implicit va=
lues.
If that is your case then there is a way around it.

Declare the datatype as=20
> data MyData =3D MyData { foo_ :: fooType, bar_ :: ..., .... }

and then declare
> foo :: (?implicitdata :: MyData)=3D> fooType
> foo =3D foo_ ?yourdata

So when you work in a contex that depends on some implicit data you can j=
ust=20
use foo. I've used this *a lot* lately.


2)
Yes. My method now is declaring set and apply functions to every field of=
 my=20
data structure.
fooAp f ni=3Dni{foo=3Df(foo ni)}
fooSet x =3D fooAp (const x)



> Only very rarely (usually only during intializization) do I actually pu=
t
> values into the structure that *don't* depend on their previous value. =
 I
> end up with expresions like:
>
> ... myData { foo =3D (foo myData) + 1 ;
>              bar =3D (bar myData) ++ "bar" ;
>              ick =3D (ick myData) ! n ; ... }

Yeap quite ugly isn't it?  :-)


> I was wondering if there existed any sort of "update" syntax.  Obviousl=
y
Nope, not that I know of.=20

> not real update, but enough to get rid of the "(foo myData)" parts of m=
y
> epxression which really serve to just clutter up with expression.  Perh=
aps
> something like:
>
> ... myData { foo <- (+1) ; bar <- (++"bar") ; ick <- (!n) ; ... }

Yes looks nice, thought about something like that before too.

> or the like, where "x { ... y <- e ... } is translated to "x { ... y =3D=
 e
> (y x) ... }"  (i only use "<-" because that seems to be the default
> extension symbol, i guess because we don't want to trample symbols peop=
le
> might actually use.)

Anyway I'd prefer to have some way to 'derive' apply and set functions.
Something like=20
> data MyData =3D MyData { foo :: fooType, bar :: ..., .... }
>  deriving (Set, Apply)

Using the keyword "deriving" would probably be a bad idea though :)
The set and apply functions could be derived with a standard postfix or m=
aybe=20
prefix... fooAp or apFoo.
Maybe we could introduce sintax to specify it...
> deriving (Set with "set", Apply with "ap")

I don't know... I'm just brainstorming right now.
Having actual functions is important. I don't think I have to explain why=
 to=20
people in this mailing list :-)

> Anyway, does such a thing exist, and, if not, is there any chance it co=
uld
> exist, or is it just syntactic salt to too many people? :)
I whish you better luck than I've had so far whenever making posts about =
this=20
same issue ;)

J.A.