From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p3T9Y0bS018400 for ; Fri, 29 Apr 2011 11:34:00 +0200 From: luc.maranget@inria.fr X-IronPort-AV: E=Sophos;i="4.64,286,1301868000"; d="scan'208";a="107062022" Received: from yquem.inria.fr ([128.93.8.37]) by mail1-relais-roc.national.inria.fr with ESMTP; 29 Apr 2011 11:33:55 +0200 Received: by yquem.inria.fr (Postfix, from userid 18041) id 53C7EE1A7E; Fri, 29 Apr 2011 11:33:55 +0200 (CEST) Date: Fri, 29 Apr 2011 11:33:55 +0200 To: Dmitry Bely Cc: caml-list@inria.fr Message-ID: <20110429093355.GA25892@yquem.inria.fr> References: <164004794.892685.1304067487325.JavaMail.root@zmbs2.inria.fr> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <164004794.892685.1304067487325.JavaMail.root@zmbs2.inria.fr> User-Agent: Mutt/1.5.18 (2008-05-17) Subject: Re: [Caml-list] Comparing variant types > > (* performs a simple comparison *) > > let f a = a <> Right > > > > (* calls out to C to do compare_val *) > > let g (a:dir) b = a <> b > > ... > > let g (a:dir) b = a != b > > - Dmitry Bely > As a general rule, don't do that! :) (using <> or != for writing 'g'). For <>, you'll get hurt by data types with non-unique representation (such as Set), as already pointed out. It is ok to use structural equality when it is not the case, but your programm is not as robust as you may want it to be. For !=, it is much worse, as soon as you add a non-constant constructor to your data type, your code is wrong (cf. [1] != [1]) If you aim at robust code. A recommended (tiresome) alternative is to write your own equality function once for all, in the following style. type dir = Left | Right | Up | Down | No_op let dir_equal d1 d2 = match d1,d2 with | (Left, Left) | (Right,Right) | (Up, Up) | (Down,Down) | (No_op,No_op) -> true | (Left,(Right|Up|Down|No_op)) | (Right,(Left|Up|Down|No_op)) | (Up,(Left|Right|Down|No_op)) | (Down,(Left|Right|Up|No_op)) | (No_op,(Down|Up|Right|Left)) -> false let g a b = not (dir_equal a b) Notice that 'let f a = a != Right' and 'let f a = a <> Right' are less dangerous, but well... --Luc