[MLton] A variation of functional record update notation

Vesa Karvonen vesa.karvonen@cs.helsinki.fi
Mon, 8 Aug 2005 06:07:09 +0300


The functional record update technique (http://mlton.org/FunctionalRecordUpdate)
uses an infix update operator, e.g. <<, to make chained updates readable:

   record << (#field1, value1)
          << (#field2, value2)
          ...
          << (#fieldN, valueN)

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

Above, `set' refers to the update function. The syntax is fairly readable
even when the update function is referred to by a longvid:

   record >| R.set#field1 value1
          >| R.set#field2 value2
          ...
          >| R.set#fieldN valueN

This way there is no need to define a separate infix operator for functional
record update.

The `fru3' function is changed to:

   fun makeSetter3 (r1, r2, t) f v r =
       let
          datatype ('a, 'b, 'c) t = A of 'a | B of 'b | C of 'c
          val (a, b, c) = t r
          fun g h value =
              r1 (case h value of A a => a | _ => a,
                  case h value of B b => b | _ => b,
                  case h value of C c => c | _ => c)
       in
          f (r2 (g A, g B, g C)) v
       end

A `set' function can be made like this:

   fun set f v s =
       let
          fun r (x1, x2, x3) = {a = x1, b = x2, c = x3}
          fun t {a = x1, b = x2, c = x3} = (x1, x2, x3)
       in
          makeSetter3 (r, r, t) f v s
       end

The `set' function can be used like this:

   {a = 1, b = 2, c = 3} >| set#a ~1
                         >| set#b ~2

-Vesa Karvonen