From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id LAA17699 for caml-redistribution; Fri, 21 Jun 1996 11:03:58 +0200 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id VAA04895 for ; Thu, 20 Jun 1996 21:11:53 +0200 Received: from nef.ens.fr (nef.ens.fr [129.199.96.12]) by concorde.inria.fr (8.7.1/8.7.1) with SMTP id VAA10554 for ; Thu, 20 Jun 1996 21:11:52 +0200 (MET DST) Received: from vedette.ens.fr by nef.ens.fr (5.65c8/ULM-1.0) Id AA29742 ; Thu, 20 Jun 1996 21:11:51 +0200 Date: Thu, 20 Jun 1996 21:11:49 +0200 (MET DST) From: Jerome Vouillon Sender: weis Reply-To: Jerome Vouillon Subject: Re: down casting ??? To: FAVRE Jean-Marie Cc: caml-list@pauillac.inria.fr In-Reply-To: <9606190903.ZM4853@tassili> Message-Id: Mime-Version: 1.0 Content-Type: TEXT/PLAIN; CHARSET=US-ASCII > the :> operator make possible to coerce an expression from a type t1 to a > super type t (this coercion is safe), but how to go from t to t1 ??? > (ok, a dynamic check is need, this operation can raise an exception) > > When one use collections of object, this kind of feature is useful. isn't it ? There are some programming tricks that lessen the need for such a feature. Here are two examples. Jerome class virtual print_interf () = virtual print : unit (* Possibly some more methods... *) end;; class opt_print () = method print_interf = (None : print_interf option) end;; class virtual can_print () as self = inherit opt_print () inherit print_interf () method print_interf = Some (self :> print_interf) end;; class a () = inherit opt_print () end;; class b () = inherit can_print () method print = print_string "xxx" end;; let x1 = new a ();; let x2 = new b ();; List.iter (function x -> match x#print_interf with None -> () | Some y -> y#print) [x1; (x2 :> a)];; (**********************************************************************) class virtual int_interf () = virtual x : int end;; class virtual string_interf () = virtual x : string end;; class virtual visitor () = virtual int : int_interf -> unit virtual string : string_interf -> unit end;; class virtual visited () = virtual accept : visitor -> unit end;; class virtual int_wrapper () as self = inherit visited () inherit int_interf () method accept visitor = visitor#int (self :> int_interf) end;; class virtual string_wrapper () as self = inherit visited () inherit string_interf () method accept visitor = visitor#string (self :> string_interf) end;; class printer () = inherit visitor () method int obj = print_int obj#x method string obj = print_string obj#x end;; class a x0 = inherit int_wrapper () val x = x0 method x = x end;; class b x0 = inherit string_wrapper () val x = x0 method x = x end;; let p = new printer ();; let x1 = new a 7;; let x2 = new b "xxx";; List.iter (function x -> x#accept p) [(x1 :> visited); (x2 :> visited)];;