Hi, Your first two examples compile without problem on my system, using either v. 3.11.2 or 4.00. If you use a parameterized registry class on the element type, you will not be able to store polymorphic values, which is, I reckon, what you probably want to achieve. I don't think there's a way to avoid casting the parameters of set to the #element superclass outside the set method. If you only have one final element class, just use the parameterized version of the registry, or replace the register method by a private register_elem method, and add a public register method in the subclass, doing the cast. Something like that : module P = struct class element id (registry :registry) = object method registry = registry end and registry = object val mutable set : element list = [] method register_elem : element -> unit = fun s -> set <- s :: set end end module I = struct class element id registry = let r = (registry :> P.registry) in object(self) inherit P.element id r as super end class registry = object(self) inherit P.registry as super method register : element -> unit = fun x -> super#register_elem (x :> P.element) end end Cheers, Didier 2012/10/24 Christopher Zimmermann > On Wed, 24 Oct 2012 20:40:27 +0200 > Gabriel Scherer wrote: > > > I don't really understand what you are trying to achieve with this > > #foo types. > > It's the simplest statement possible to demonstrate the typing error I > ran into. Even simpler: > > class type a = object end > and b = > object > method foo: 'a. (#a as 'a) -> unit > end > > fails, but > > class type a = object end > class type b = > object > method foo: 'a. (#a as 'a) -> unit > end > > > works fine. Why? > > > What would even be the type of "set" in your example? You > > cannot hold a mutable reference to a polymorphic type (#element list), > > so I'm not sure what you would have but (element list). > That's correct. It should read > val mutable set = [] > method register :'a. (#element as 'a) -> unit = > fun s -> > set <- (s : #element :> element) :: set > > > If you're > > going to coerce your elements into the common (element) supertype > > anyway, why insist on having flexible bounds? You could just use > > (registry) and (element), coerce when needed (foo :> element), and get > > rid of those pesky typing issues. > > That's my current workaround for this issue. But I would prefer a > solution where the coercion happens in the registry. > > > > > On Wed, Oct 24, 2012 at 8:03 PM, Christopher Zimmermann > > wrote: > > > Hi, > > > > > > I have a problem with typing a system of mutually recursive classes. > > > > > > This piece of code fails to compile: > > > > > > class a = > > > object end > > > and b = > > > object > > > method foo: a -> int = > > > fun s -> 3 > > > end;; > > > > > > Error: The universal type variable 'a cannot be generalized: > > > it escapes its scope. > > > > > > > > > But this compiles fine: > > > > > > class a = > > > object end > > > class b = > > > object > > > method foo: 'a. (#a as 'a) -> int = > > > fun s -> 3 > > > end;; > > > > > > > > > What I actually want to do is this: > > > > > > class element id (registry :#registry) = > > > object > > > method registry = registry > > > end > > > > > > and registry = > > > object > > > val set = [] > > > method register :'a. (#element as 'a) -> unit = > > > fun s -> > > > set <- s :: set > > > end > > > > > > > > > Any ideas how to do this without parametrizing the classes? > > > > > > Christopher > > > -- > 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 >