It is possible to generalize this approach using private row types.
list_fns.mli:
module Registry(Obj : sig
val register_obj : string -> Obj.t -> unit
val get_obj : string -> Obj.t
module Registry(Obj : sig
let register_obj name obj = objs := (name, obj) :: !objs
let get_obj name = List.assoc name !objs
method hello = "hello from foo"
method goodbye () = print_endline "goodbye"
method hello = "hello from bar"
module Bars = List_fns.Registry(struct type t = bar end)
Bars.register_obj "o1" (o1 :> bar);
Bars.register_obj "o2" (o2 );
print_endline ("calling o1: " ^ (Bars.get_obj "o1")#hello);
print_endline ("calling o2: " ^ (Bars.get_obj "o2")#hello)
The List_fns.Registry functor will create a monomorphic registry for the specified base type.
Probably, this may help you :)
Best wishes,
Ivan Gotovchits