[MLton] A variation of functional record update notation
Stephen Weeks
MLton@mlton.org
Mon, 8 Aug 2005 15:02:55 -0700
> It occured to me that if you curry the update function and reorder the
> parameters, you can use the left piping operator (http://mlton.org/InfixingOperators)
> and still have a fairly readable notation:
>
> record >| set#field1 value1
> >| set#field2 value2
> ...
> >| set#fieldN valueN
...
> This way there is no need to define a separate infix operator for functional
> record update.
Nice. I've been using a similar approach recently in some code where
I wanted a convenient syntax for imperative record update. Here's an
example. Suppose we have some object type X.t, where such objects
have a settable "n", "s", and "x" field. Define the setters, as you
did, to be curried and to take the object last.
------------------------------------------------------------
signature X =
sig
type t
val s: t
structure Set:
sig
val n: int -> t -> unit
val s: string -> t -> unit
val x: real -> t -> unit
end
end
------------------------------------------------------------
Then, define a combinator to combine setters.
------------------------------------------------------------
infix 4 &
val op & : ('a -> unit) * ('a -> unit) -> 'a -> unit =
fn (f, g) => fn a => (f a; g a)
------------------------------------------------------------
Now, it is easy to set whatever fields you want.
------------------------------------------------------------
functor F (X: X) =
struct
structure S = X.Set
val () = X.s >| S.n 13 & S.s "foo" & S.x 17.0
end
------------------------------------------------------------
An alternative to introducing the new infix "&" operator is to change
the type of the setters to return the object. Then, one could just
use pipe, as in
val _ = X.s >| S.n 13 >| S.s "foo" >| S.x 17.0
But I find the "&" combinator useful because one can treat collections
of attributes as a single attribute, and share it across multiple
objects, as in
val a = S.n 13 & S.s "foo"
val () = X.s1 >| a & S.x 17.0
val () = X.s2 >| a & S.x 19.0
> Do you think that it would make sense to provide a simple script
> (maybe Emacs lisp) to generate a signature/structure (say
> RECORDS/Records) of makeSetter -functions (upto desired N) and
> change the FRU-page to use the piping notation?
I have no objection to the page being changed. I think the new
approach is more useful too. The fewer infixes the better.