From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id JAA25885 for caml-redistribution; Thu, 28 Jan 1999 09:18:24 +0100 (MET) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id DAA07332 for ; Thu, 28 Jan 1999 03:37:46 +0100 (MET) Received: from zarya.maya.com (zarya.maya.com [192.70.254.128]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id DAA28495 for ; Thu, 28 Jan 1999 03:37:44 +0100 (MET) Received: (from prevost@localhost) by zarya.maya.com (8.8.7/8.8.7) id VAA08744; Wed, 27 Jan 1999 21:37:23 -0500 Sender: weis To: caml-list@inria.fr Subject: Repeat: Question about corecursive type and class types (w/ answer) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii From: John Prevost Date: 27 Jan 1999 21:37:22 -0500 Message-ID: User-Agent: Gnus/5.070072 (Pterodactyl Gnus v0.72) Emacs/20.3 I asked this a bit ago, but didn't receive any answer. In order to do something like restricted downcasting, I'd like to say something equivalent to the following: type objsum = | A of a | B of b and class type super = object method as_objsum : objsum ... end and class type a = object inherit super ... end and class type b = object inherit super ... end I was not able to do the above because you can't define a type and a class type in the same set of and s. I was able to do the following: type objsum' = | A' of a' | B' of b' and super = < to_objsum' : objsum'; ... > and a = < to_objsum' : objsum'; ... > and b = < to_objsum' : objsum'; ... > This second version is rather less acceptable, since if the class type has a large number of methods (as can occur when you're doing a bit of inheritance), there can be problems. I've finally discovered a way to do what I want to do--although I think it may be possible to make it easier to define. (I was looking at the parser, and it didn't seem easy to make the change, though.) Here's the workaround: class type ['a] super = object method downcast : 'a end class type ['a] a = object inherit ['a] super method do_a : int end class type ['a] b = object inherit ['a] super method do_b : float end type objsum = | A of objsum a | B of objsum b And to show that it works, the following (with the above assumed): # class test_a = object (s) method downcast = A (s :> objsum a) method do_a = 1 end class test_b = object (s) method downcast = B (s :> objsum b) method do_b = 1.0 end;; class test_a : object method do_a : int method downcast : objsum end class test_b : object method do_b : float method downcast : objsum end # let ta = new test_a let tb = new test_b;; val ta : test_a = val tb : test_b = # let ta' = (ta :> objsum super) let tb' = (tb :> objsum super);; val ta' : objsum super = val tb' : objsum super = # ta'#do_a;; Characters 0-3: This expression has type objsum super It has no method do_a # let (A ta'3) = ta'#downcast let (B tb'3) = tb'#downcast;; Characters 5-11: Warning: this pattern-matching is not exhaustive. Characters 34-40: Warning: this pattern-matching is not exhaustive. val ta'3 : objsum a = val tb'3 : objsum b = # ta'3#do_a;; - : int = 1 # tb'3#do_b;; - : float = 1