[MLton] Slightly simpler functional record update
Stephen Weeks
MLton@mlton.org
Fri, 12 Aug 2005 09:48:00 -0700
> in the definition of set complicated enough to be worth abstracting
> into a makeSetter3 function. I like separating the update from the
> conversions, but I think it makes the isomorphism clearer to define
> the set function via makeSetter3 as follows.
>
> ----------------------------------------------------------------------
> fun makeSetter3 (r1, r2, t) f z s = r1 (set3 (f o r2) z (t s))
It occurs to me that there is nothing specific to 3-tuples in the
concept of converting a tuple-setter into a record-setter. So, we
could use a generic wrapSet as follows.
----------------------------------------------------------------------
fun wrapSet (set, r1, r2, t) f z s = r1 (set (f o r2) z (t s))
fun set2 f v (v1, v2) =
let
datatype ('v1, 'v2, 'v3) t =
V1 of 'v1 | V2 of 'v2
fun g h v =
(case h v of V1 v1 => v1 | _ => v1,
case h v of V2 v2 => v2 | _ => v2)
in
f (g V1, g V2) v
end
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
fun set f =
let
fun r (a, b) = {a = a, b = b}
fun t {a, b} = (a, b)
in
wrapSet (set2, r, r, t) f
end
val r = {a=1, b=1} >| set#b ~2 >| set#a ~1
fun set f =
let
fun r (a, b, c) = {a = a, b = b, c = c}
fun t {a, b, c} = (a, b, c)
in
wrapSet (set3, r, r, t) f
end
val r = {a=1, b=1, c=1} >| set#b ~2 >| set#a ~1 >| set#c ~3