From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 6E5BBBC28 for ; Thu, 4 Nov 2004 00:33:13 +0100 (CET) Received: from ig2.scea.com (ig2.scea.com [160.33.44.35]) by concorde.inria.fr (8.13.0/8.13.0) with ESMTP id iA3NXCIU018875 for ; Thu, 4 Nov 2004 00:33:12 +0100 Received: from edenfox.989studios.com (edenfox.989studios.com [160.33.45.60]) by ig2.scea.com (8.12.10/8.11.3) with ESMTP id iA3NXFIr7392119 for ; Wed, 3 Nov 2004 15:33:15 -0800 (PST) X-Envelope-To: Received: from slave-dog.naughtydog.com ([10.15.0.2]) by edenfox.989studios.com (8.12.10/8.12.10/SCEAint-1.0) with SMTP id iA3NX9id028122 for ; Wed, 3 Nov 2004 15:33:09 -0800 Received: from SMTP agent by mail gateway Wed, 03 Nov 2004 15:31:59 -0800 Received: from katn-dog.naughtydog.com (engstad@katn-dog.naughtydog.com [10.0.0.90]) by slave-dog.naughtydog.com (SGI-8.12.5/8.12.5) with ESMTP id iA3NVuE6084057 for ; Wed, 3 Nov 2004 15:31:56 -0800 (PST) From: Pal-Kristian Engstad Organization: Naughty Dog, Inc. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Self type cannot be unified with a closed object type Date: Wed, 3 Nov 2004 15:31:55 -0800 User-Agent: KMail/1.7 References: In-Reply-To: MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200411031531.55805.pal_engstad@naughtydog.com> X-Scanned-By: MIMEDefang 2.35 X-Miltered: at concorde with ID 41896AB8.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; caml-list:01 wrote:01 ocaml:01 ocaml:01 parses:01 recursive:01 mutable:01 val:01 mutable:01 val:01 pke:01 stub:01 stub:01 coerce:01 int:01 X-Spam-Checker-Version: SpamAssassin 3.0.0 (2004-09-13) on yquem.inria.fr X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.0.0 X-Spam-Level: On Tuesday 02 November 2004 03:42 pm, Philippe Meunier wrote: > Hi, > > I'm trying to implement the state pattern in Ocaml and I'm looking for > help. I have two classes itv1 and itv2 representing two kinds of > state. I'm trying to coerce objects from these two classes to a > single class nl_v so I can use them indefferently inside objects of > the class anl: Hi, The state pattern is useful in OO languages since switches aren't safe. However, I will assume that you do need to extend the state class, so I won't go on about how you can use union types. Your only problem is that the 'self' type is extendible. Therefore, while OCaml parses your recursive structure, there is no specific closed type of self. If the type of 'self' was closed, then you could not extend your class. The easiest solution in your case is to make adapt return a closed type, namely your nl_vp class type. Simply change "method adapt : 'a" to "method adapt: nl_vp": type itv2stub = { mutable ival : int } let new_itv2_stub () = { ival = 0 } let get_itv2_stub s = s.ival let set_itv2_stub s v = (s.ival <- v; s) class type nl_vp = object method get : int method set : int -> nl_vp method adapt : nl_vp end;; class itv1 : nl_vp = object (self) val mutable itv1_val = ~-1 method get = itv1_val method set i = {< itv1_val = i >} method adapt = if self#get = 2 then (new itv2 :> nl_vp) else (self :> nl_vp) end and itv2 : nl_vp = object (self) val mutable itv2_val = new_itv2_stub () method get = get_itv2_stub itv2_val method set i = {< itv2_val = set_itv2_stub itv2_val i >} method adapt = if self#get = 7 then ((new itv1) :> nl_vp) else (self :> nl_vp) end;; class anl = object val mutable nl = (new itv1 :> nl_vp) method get = nl#get method set i = {< nl = (nl#set i)#adapt >} method adapt = {< nl = nl#adapt >} end;; By the way, notice that {< itv1_val = i >} creates a _new_ object, hence it might not do what you expect. I.e. the "mutable" keyword is not nescessary in itv1. Hope this helps. PKE.