[MLton] Slightly simpler functional record update
Vesa Karvonen
vesa.karvonen@cs.helsinki.fi
Thu, 11 Aug 2005 01:33:26 +0300
Thinking about the functional record update technique, a couple of things
occured to me. First of all, functional record update makes sense for
plain tuples (which are really a form of record in SML). Also, the `fruN'
(or the `makeSetterN') functions seem to be doing two separable things:
- perform a "functional tuple update", and
- convert from a record to a tuple and back.
Starting from `makeSetter3', I simplified it to `set3', which performs a
functional 3-tuple update:
fun set3 f v (v1, v2, v3) =
let
datatype ('v1, 'v2, 'v3) t =
V1 of 'v1 | V2 of 'v2 | V3 of 'v3
fun g h v =
(case h v of V1 v1 => v1 | _ => v1,
case h v of V2 v2 => v2 | _ => v2,
case h v of V3 v3 => v3 | _ => v3)
in
f (g V1, g V2, g V3) v
end
The `set3' function can be used like this:
(1, 2, 3) >| set3#2 ~2 >| set3#1 ~1 >| set3#3 ~3
Then I wrote a `set' function for the record {a, b, c} using `set3':
fun set f v {a = v1, b = v2, c = v3} =
let
fun r (v1, v2, v3) = {a = v1, b = v2, c = v3}
in
r (set3 (f o r) v (v1, v2, v3))
end
The `set' function can be used, as usual, like this:
{a=1, b=1, c=1} >| set#b ~2 >| set#a ~1 >| set#c ~3
This formulation is slightly simpler (meaning the implementation requires
slightly less code) than the one based on `fruN' (or `makeSetterN') functions.
In addition, the functional tuple update, `setN', operations can be useful
on their own.
I think that this formulation may also be a bit easier to understand, because
the conversions (tuple <-> record) and the tuple update are now separated (and
can be understood on their own). Also, there is no need to mention first class
(or rank-2) polymorphism.
-Vesa Karvonen