From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.4 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id B8584BBC4 for ; Thu, 2 Apr 2009 10:39:17 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ApoEAEcW1EmFBoIF/2dsb2JhbADPGQEEg30 X-IronPort-AV: E=Sophos;i="4.39,313,1235948400"; d="scan'208";a="37708155" Received: from rabbit.math.nagoya-u.ac.jp (HELO mailhost.math.nagoya-u.ac.jp) ([133.6.130.5]) by mail4-smtp-sop.national.inria.fr with ESMTP; 02 Apr 2009 10:39:16 +0200 Received: from mailhost.math.nagoya-u.ac.jp (localhost [127.0.0.1]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTP id CBB58B661; Thu, 2 Apr 2009 17:39:13 +0900 (JST) Received: from mailhost.math.nagoya-u.ac.jp (localhost [127.0.0.1]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTP id 572C28885; Thu, 2 Apr 2009 17:39:13 +0900 (JST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=math.nagoya-u.ac.jp; h= date:message-id:to:cc:subject:from:in-reply-to:references :mime-version:content-type:content-transfer-encoding; s=alpha; bh=blw3ve59Tf9BJcLe5D3yKYfj11Y=; b=RJ15cLpTlJGdJd6oN3tKyvwUOPd9 EzAj15AZNKHaapkNMQXs6f8PT+plsfU+8Y6QeqcFniOJJjewVlSB/LyRW221gcXu AYImDRyNKZvSBUifClR8fUTD+p7tCP/grm7FyYJwf4Xg8BVDBtz1G28CU3aWPhaT Jg1O00wPz+yYFDw= DomainKey-Signature: a=rsa-sha1; h=Received:Date:Message-Id:To:Cc:Subject:From:In-Reply-To:References:X-Mailer:Mime-Version:Content-Type:Content-Transfer-Encoding; b=YiFa6fC0ZHZv718V3OOQHxiIXfoZymNY8+FwKQW4/8J/U7nj9/uTsCsCo2fIp5u70HTUy2FxJWN4mgwJT/ondeT+yMK34ucZI0kQDY8jIg0RgV3b3i93DZ6N8kRqeTSKmh0O9YXTFdH4ysTj9IkE+2yXLpZfAkrnUUNNdu7V0O4=; c=nofws; d=math.nagoya-u.ac.jp; q=dns; s=alpha Received: from localhost (rabbit-172 [172.16.254.254]) by mailhost.math.nagoya-u.ac.jp (Postfix) with ESMTPSA id 1859F8883; Thu, 2 Apr 2009 17:39:13 +0900 (JST) Date: Thu, 02 Apr 2009 17:39:11 +0900 (JST) Message-Id: <20090402.173911.68542703.garrigue@math.nagoya-u.ac.jp> To: goswin-v-b@web.de Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Bug? Constraints get ignored in methods From: Jacques GARRIGUE In-Reply-To: <87ab71ic1f.fsf@frosties.localdomain> References: <87ab71ic1f.fsf@frosties.localdomain> X-Mailer: Mew version 6.1 on Emacs 22.3 / Mule 5.0 (SAKAKI) Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; bug:01 subset:01 ocaml:01 subset:01 val:01 mutable:01 foo:01 foo:01 coercions:01 ocaml:01 val:01 mutable:01 verbose:01 polymorphic:01 caml-list:01 From: Goswin von Brederlow > I want to keep a linked list of structures that have a common subset > of functionality. I thought this would be a good use of ocaml objects. > A base class with the common subset of functionality and methods to > link them. And then derived classes for the specific types. Most > simplified it looks like this: > > # class type base_type = object val mutable next : base_type option method set_next : base_type option -> unit end;; [...] > # class foo = object inherit base method foo = () end;; [...] > # let a = new base in > let b = new foo in > a#set_next (Some (b :> base_type));; > - : unit = () > > I don't want to have to cast the objects > all the time. So I thought there must be a better way using > polymorphic methods with a constraint. But here is where everything > breaks down. First lets look at just the set_next method: >>From your other posts I gather that your objects have a uniform interface once they are in the list, and a specific interface just after creating them. Hopefully you never need to recover the specific interface from an object in a list (if that were the case, then I strongly suggest using normal sum types...) You don't want to write the coercions. That's natural. I see two ways out. One is to realize that a method is just a weaker function, so just write a function doing the coercion: let set_next (x : #base_type) y = x#set_next (Some (y :> base_type)) You might not like using a function, but you just have to realize that methods are kind of second class in ocaml... If you really want to stick to methods only (because of library design, for instance), then a clever trick is to use a coercion methods: class virtual base_type = object (self) val mutable virtual next : base_type option method virtual set_next_base : base_type option -> unit method as_base = (self :> base_type) method set_next : 'a. as 'a -> unit = fun x -> self#set_next_base x#as_base end This may seem verbose here, but self-coercion methods are a good idea anyway. Hope this helps, Jacques Garrigue