We can make fields in records mutable. Let's define points with colors, where the color is mutable.
type point = {
x: int;
y: int;
mutable c: string;
}
type point = { x : int; y : int; mutable c : string; }
Note that mutable goes before the field name, it's not part of the type (i.e. it's not a mutable string or anything).
Now let's make a point
let p = {x = 0; y = 0; c = "red"}
val p : point = {x = 0; y = 0; c = "red"}
And let's update the color
p.c <- "white";;
- : unit = ()
p;;
- : point = {x = 0; y = 0; c = "white"}
Now the field in point p has been updated to be "white" instead of "red". We can't do this to the other fields:
p.x <- 1;;
File "[5]", line 1, characters 0-8:
1 | p.x <- 1;;
^^^^^^^^
Error: The record field x is not mutable
Notice that the mutation operator for mutable fields is not the same as the one for refs. We can actually implement refs ourselves!
type 'a ref = { mutable contents : 'a }
let ref x = { contents = x }
let ( ! ) r = r.contents
let ( := ) r newval = r.contents <- newval
type 'a ref = { mutable contents : 'a; }
val ref : 'a -> 'a ref = <fun>
val ( ! ) : 'a ref -> 'a = <fun>
val ( := ) : 'a ref -> 'a -> unit = <fun>
The type is declared in the standard library (they're actually compiled to external functions, but they behave very similarly, see here)