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 mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 0F518BBAF for ; Tue, 20 Jan 2009 17:44:26 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtgEAHiOdUmCcUBTgWdsb2JhbACUBwEBCwcECgcRt0WFcw X-IronPort-AV: E=Sophos;i="4.37,295,1231110000"; d="scan'208";a="22793934" Received: from sigma957.cis.mcmaster.ca ([130.113.64.83]) by mail1-smtp-roc.national.inria.fr with ESMTP; 20 Jan 2009 17:44:24 +0100 Received: from Dura7.UTS.McMaster.CA (dura7.UTS.mcmaster.ca [130.113.196.62]) by sigma957.cis.mcmaster.ca (8.13.7/8.13.7) with ESMTP id n0KGhrSJ028892 for ; Tue, 20 Jan 2009 11:44:20 -0500 (EST) Received: from cgpsrv2.cis.mcmaster.ca (univmail.CIS.McMaster.CA [130.113.64.46]) by Dura7.UTS.McMaster.CA (8.13.7/8.13.7) with ESMTP id n0KGgfxZ031507 for ; Tue, 20 Jan 2009 11:43:34 -0500 Received: from [129.97.84.95] (account carette@univmail.cis.mcmaster.ca HELO [192.168.1.109]) by cgpsrv2.cis.mcmaster.ca (CommuniGate Pro SMTP 4.3.12) with ESMTPSA id 239313808 for caml-list@inria.fr; Tue, 20 Jan 2009 11:43:30 -0500 Message-ID: <4975FF31.90900@mcmaster.ca> Date: Tue, 20 Jan 2009 11:43:29 -0500 From: Jacques Carette User-Agent: Thunderbird 2.0.0.19 (Windows/20081209) MIME-Version: 1.0 To: caml-list@inria.fr Subject: private types - suggestion Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-PMX-Version-Mac: 5.4.2.338381, Antispam-Engine: 2.6.0.325393, Antispam-Data: 2009.1.20.162528 X-PerlMx-Spam: Gauge=IIIIIII, Probability=7%, Report='BODY_SIZE_2000_2999 0, BODY_SIZE_5000_LESS 0, __CT 0, __CTE 0, __CT_TEXT_PLAIN 0, __HAS_MSGID 0, __MIME_TEXT_ONLY 0, __MIME_VERSION 0, __SANE_MSGID 0, __USER_AGENT 0' X-Spam: no; 0.00; compiler:01 bug:01 indirection:01 experimented:01 annotations:01 sig:01 struct:01 failwith:01 failwith:01 polymorphic:01 incompatible:01 compiles:01 pps:01 variant:02 match:02 [See full code below] I have encountered a fairly subtle issue with private types which doesn't occur otherwise. The source of the issue, I believe, is actually the need to have a 'row variable' available to be able to use 'private' on a polymorphic variant. In the code below (a massive simplification of my actual case), f compiles, but g does not, with error Error: This pattern matches values of type [> `Operator of 'a * 'b list * 'c S.pk ] but is here used to match values of types S.operator Types for tag `Operator are incompatible (pointing to the line that starts with | `Operator ...) First suggestion: could the error message please include what the incompatibility is? Second suggestion: could the type S.operator be (also) given in its 'expanded' form? It would be useful to know what the compiler thinks the type S.operator actually is. Third suggestion: in this particular case, could the error message include some hints that the problem is one of [< ] vs [> ] ? [if my understanding of the issue is correct!] I will add these suggestions to the bug system next, but I figured others on this list might benefit from my experience in debugging this issue in my code. Jacques PS: I actually don't want the intermediate type pk, po, pb and ps to be visible at all outside of S, but I do not know how to achieve that without adding another layer of indirection. Any advice along these lines would be appreciated. PPS: I experimented with variance annotations too, thinking that that might do the trick, but to no avail. --- module S : sig type 'a pk = KType | KFormula | Kind of 'a pb and 'a po = [`Operator of string * 'a pk list * 'a pk ] and 'a pb = [`Thing of string] type 'a ps = ['a po | 'a pb] type se = se ps type operator = private [< se po] end = struct type 'a pk = KType | KFormula | Kind of 'a pb and 'a po = [`Operator of string * 'a pk list * 'a pk ] and 'a pb = [`Thing of string] type 'a ps = ['a po | 'a pb] type se = se ps type operator = se po end open S (* this one works *) let f (o:operator) : string = match o with | `Operator(s, [], S.KType) -> s | `Operator(_,_,_) -> failwith "nope" (* this one doesn't ! *) let g (o:operator) : string = match o with | `Operator(s, [], S.KType) -> s | _ -> failwith "nope" ;;