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=AWL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr 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 44F38BB84 for ; Mon, 14 Jul 2008 21:37:55 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AncAAENHe0jUnvgImmdsb2JhbACSLwEBAQEBCAUIBxEDmVE X-IronPort-AV: E=Sophos;i="4.30,360,1212357600"; d="scan'208";a="15096634" Received: from smtp.bulldogdsl.com (HELO mcr-smtp-002.bulldogdsl.com) ([212.158.248.8]) by mail1-smtp-roc.national.inria.fr with ESMTP; 14 Jul 2008 21:37:54 +0200 Received: by mcr-smtp-002.bulldogdsl.com (Postfix, from userid 1010) id 77DB7846405; Mon, 14 Jul 2008 20:37:51 +0100 (BST) Received: from [192.168.123.191] (host-84-9-232-7.dslgb.com [84.9.232.7]) by mcr-smtp-002.bulldogdsl.com (Postfix) with ESMTP id 9C31B845BA3; Mon, 14 Jul 2008 20:37:48 +0100 (BST) Message-ID: <487BAB0B.6030000@ed.ac.uk> Date: Mon, 14 Jul 2008 20:37:47 +0100 From: Jeremy Yallop User-Agent: Mozilla-Thunderbird 2.0.0.14 (X11/20080509) MIME-Version: 1.0 To: Dario Teixeira Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Troublesome nodes References: <831.74975.qm@web54604.mail.re2.yahoo.com> In-Reply-To: <831.74975.qm@web54604.mail.re2.yahoo.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; nodes:01 node:01 generative:01 denotes:01 module-level:01 bindings:01 denoting:01 ocaml:01 bindings:01 node:01 polymorphic:01 wrote:01 abstract:01 abstract:01 syntactic:01 Dario Teixeira wrote: > type ('a, 'b) t = private 'a constraint 'a = [< super_node_t ] I don't think this is quite what you want yet, although it's getting close! The first problem is that phantom types must be implemented in terms of abstract (or at least generative) types. A simple example to illustrate the problem: the types int t and float t denote the same type given the alias declaration type 'a t = unit but different types given the abstract type declaration type 'a t The clause "= private 'a" in your declaration above indicates that `t' denotes an alias, not an abstract type. The second problem is indicated by the error message you reported: "The type of this expression contains type variables that cannot be generalized" Weak (ungeneralised) type variables are not allowed at module-level bindings. You'll see a similar error message if you try to compile a module containing the following binding, for example let x = ref None The solution to this problem is usually to change the form of the offending expression, for example by eta-expanding a term denoting a function. In your case, though, the solution is to change the declaration of the abstract type `t' to indicate that the type parameters do not occur negatively in the right-hand side. This takes advantage of a novel feature of OCaml -- the "relaxed value restriction" -- which uses a subtype-based analysis rather than a simple syntactic check to determine whether bindings can be made polymorphic. The final type declaration, then, is type (+'a, +'b) t constraint 'a = [< super_node_t ] in the signature and type (+'a, +'b) t = 'a constraint 'a = [< super_node_t ] in the implementation. Jeremy.