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.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id 4D951BB83 for ; Fri, 1 Sep 2006 21:26:31 +0200 (CEST) Received: from ptb-relay03.plus.net (ptb-relay03.plus.net [212.159.14.214]) by nez-perce.inria.fr (8.13.6/8.13.6) with ESMTP id k81JQULA002067 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO) for ; Fri, 1 Sep 2006 21:26:30 +0200 Received: from [80.229.56.224] (helo=[10.0.0.5]) by ptb-relay03.plus.net with esmtp (Exim) id 1GJEef-0007DD-KL for caml-list@yquem.inria.fr; Fri, 01 Sep 2006 20:26:17 +0100 From: Jon Harrop Organization: Flying Frog Consultancy Ltd. To: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Polymorphic variants question Date: Fri, 1 Sep 2006 20:26:39 +0100 User-Agent: KMail/1.9.3 References: <012901c6cdec$64edf490$6a7ba8c0@treble> In-Reply-To: <012901c6cdec$64edf490$6a7ba8c0@treble> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200609012026.40067.jon@ffconsultancy.com> X-Miltered: at nez-perce with ID 44F88966.001 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; variants:01 val:01 bool:01 ad-hoc:01 bool:01 val:01 lexers:01 high-level:01 lexers:01 subset:01 lexer:01 type-checker:01 subset:01 superset:01 checker:01 On Friday 01 September 2006 18:31, David Allsopp wrote: > let f x = if x = `A then (true, `B) else (false, x);; You probably want: # let f = function `A -> true, `B | `C -> false, `C;; val f : [< `A | `C ] -> bool * [> `B | `C ] = > then I get a type error unless I change > (false, x) > to > (false, id x) Use coercion :> instead of an ad-hoc function: # let (f : [`A | `C] -> bool * [`A | `B | `C]) = fun x -> if x = `A then (true, `B) else (false, (x :> [`A|`B|`C]));; val f : [ `A | `C ] -> bool * [ `A | `B | `C ] = > Is there a better way of writing this? I'm using this in the context of > several interrelated lexers where `A, `B and `C are high-level states and > certain lexers can only be called in a subset of those states but each > lexer may yield any value for the next-state. I'd quite like to eliminate > the id x bit since it's only there to "separate" x from the return value > for the type-checker. Note that the type of your id function is not 'a -> 'a: # let id = function `A -> `A | `C -> `C;; val id : [< `A | `C ] -> [> `A | `C ] = So it accepts a subset of {A, C} and returns a type that unifies with any superset of {A, C}. To leverage static type checking you must provide as much information as possible to the static type checker. In this case, rather than using "if" to denote `A or not `A, you can just as easily use pattern matching to imply specifically `A or `C. -- Dr Jon D Harrop, Flying Frog Consultancy Ltd. Objective CAML for Scientists http://www.ffconsultancy.com/products/ocaml_for_scientists