I am attempting to create a procedural object language system in OCaml. The general idea is to store values of polymoprhic variants in an array and let procedures update this array (imperatively):
module StrMap = Map.Make(String)
module IntMap = Map.Make(struct type t = int let compare = compare end)
(* store generic labeled objects *)
type 'a env = ([> ] as 'a) IntMap.t
(* a procedure working on such an object array *)
type 'a procedure = 'a env -> 'a env
(* store procedures *)
type 'a proc_table = ('a procedure) StrMap.t
let do_iinc = function
| `Int n -> `Int (n+1)
let iinc x env =
let v = do_iinc (IntMap.find x env) in
IntMap.add x v env
let do_finc = function
| `Float f -> `Float (f +. 1.0)
let finc x env = IntMap.add x (do_finc (IntMap.find x env)) env
(* type error :( *)
let table =
StrMap.add "iinc" (iinc 0)
(StrMap.add "finc" (finc 1)
StrMap.empty)
This puzzles me. My "update" is invariant for a concrete type. Shouldn't OCaml be able to figure out that table : ([`Float of float ; `Int of int ] procedure) StrMap.t
?
I suspect the problem has to do with the variance of map, but I fail to confirm it, since I cannot annotate the type with the concrete polymorphic variants.
Is my idea even feasible in OCaml?