Source

ocaml-pure-polyrecord / test.ml

Full commit
(* Record creation 

   {| .. |} is a record but all the fields are immutable.
   If you want to have mutability, use ref explicitly.
*)

let r = {| x = 1; y = ref None |}

(* Record access

   r..field

*)

let () = match r..x + 2 with 3 -> prerr_endline "ok" | _ -> assert false

(* Non existent field access is statically rejected.

let z = r..z

*)

(* You can define polymorphic accessor, however. *)

let get_z r = r..z

let get_z_w r = r..z..w

(* Marshalling. Those records are just hashtbls, so streamable *)

let () = output_value stdout r; print_newline ()

(* Making a copy with 

   {| r with bindings |}

*)

let r2 = {| r with x = 3 |}

(* You cannot add fields at copy. :-(

   let r2 = {| r with z = 3 |} 

*)

(* You can forget fields via explicit coercion *)

let r3 = (r2 :> < x : int > Polyrecord.t)

(* Mutability via ref member by 

   r..field <- e

*)

let () = r2..y <- Some 3;; 

(* Mutable field cannot have poly type

   let () = r2..y <- Some 3.0 (* error *)
*)

(* Accessing the content of the mutable field is via (!).
   A bit glitchy... 
*)

let () = Printf.printf "%d\n" (match !(r2..y) with None -> -1 | Some v -> v)

(* !r..y = (!r)..y  not  !(r..y)

   just like !r.y = (!r).y  not  !(r.y)

*)

let g r = !r..y


(* Nicely prevents multi uses of a label

  let strange = {| x = 1; x = 1.0 |}

*)

(* No pattern matching 

   let () = match r with
     | {| x = 1 |} -> true
     | _ -> false

*)