Hi Richard, Note that you can still write < hello: string; .. > in the signature of register_obj and do the cast before adding your object to the list: let register_obj name obj = objs := (name, (obj :> < hello: string >)) :: !objs This way you do not need to downcast at each call-site of register_obj. Cheers, Nicolas On Wed, Feb 22, 2017 at 6:36 PM, Richard W.M. Jones wrote: > On Wed, Feb 22, 2017 at 12:09:37PM -0500, Gabriel Scherer wrote: > > The signature you demand is actually incorrect, because the return > > type of get_obj is to permissive: it claims that it can return *any* > > ('a obj), so you could register an object with just the hello method > > and get back an object with more methods. > > > > On the other hand, if you use the monomorphic < hello : string > type > > in the interface, then it is type-correct and the implementation you > > provide is accepted. It is explicit in the fact that you can't recover > > the extra methods of the object once they have been stored in this > > lowest-common-denominator container. > > Ah, I see. > > Modifying the code to use the monomorphic type works, but I have to > downcast the objects to the right type. For reference, the working > code is below. > > Thanks, > > Rich. > > list_fns.mli -------------------------------------------------------- > type obj = < hello : string > > val register_obj : string -> obj -> unit > val get_obj : string -> obj > > list_fns.ml --------------------------------------------------------- > type obj = < hello : string > > let objs = ref [] > let register_obj name obj = objs := (name, obj) :: !objs > let get_obj name = List.assoc name !objs > > test.ml ------------------------------------------------------------- > class foo = object > method hello = "hello from foo" > method goodbye () = print_endline "goodbye" > end > > class bar = object > method hello = "hello from bar" > end > > let () = > let o1 = new foo in > let o2 = new bar in > List_fns.register_obj "o1" (o1 :> List_fns.obj); > List_fns.register_obj "o2" (o2 :> List_fns.obj); > print_endline ("calling o1: " ^ (List_fns.get_obj "o1")#hello); > print_endline ("calling o2: " ^ (List_fns.get_obj "o2")#hello) > -------------------------------------------------------------------- > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa.inria.fr/sympa/arc/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs >