From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 AFAC2BBAF for ; Mon, 17 May 2010 18:37:18 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmUEAMcN8UvZSMDjdWdsb2JhbACdeRUBFyAFH7wnhRAE X-IronPort-AV: E=Sophos;i="4.53,248,1272837600"; d="scan'208";a="59507817" Received: from fmmailgate02.web.de ([217.72.192.227]) by mail1-smtp-roc.national.inria.fr with ESMTP; 17 May 2010 18:37:18 +0200 Received: from smtp05.web.de ( [172.20.4.166]) by fmmailgate02.web.de (Postfix) with ESMTP id D8A8B160FA252; Mon, 17 May 2010 18:37:17 +0200 (CEST) Received: from [78.43.204.177] (helo=frosties.localdomain) by smtp05.web.de with asmtp (TLSv1:AES256-SHA:256) (WEB.DE 4.110 #4) id 1OE3Jd-0005k8-00; Mon, 17 May 2010 18:37:17 +0200 Received: from mrvn by frosties.localdomain with local (Exim 4.71) (envelope-from ) id 1OE3Ji-0000yK-PG; Mon, 17 May 2010 18:37:22 +0200 From: Goswin von Brederlow To: Thomas Braibant Cc: caml-list@yquem.inria.fr Subject: Re: [Caml-list] Phantom types References: Date: Mon, 17 May 2010 18:37:22 +0200 In-Reply-To: (Thomas Braibant's message of "Mon, 17 May 2010 16:59:52 +0200") Message-ID: <87y6fiwkl9.fsf@frosties.localdomain> User-Agent: Gnus/5.110009 (No Gnus v0.9) XEmacs/21.4.22 (linux, no MULE) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Sender: goswin-v-b@web.de X-Sender: goswin-v-b@web.de X-Provags-ID: V01U2FsdGVkX19HOPpWkVn49vOzQkkMlVDsPVSVIn7jXmYCyCim PCTkFKT0Bb847grG4pi6v6UxFP+f64zd5D7sLp/V5VY6XQE54b wdmcqnhQU= X-Spam: no; 0.00; subtyping:01 ocaml:01 submodule:01 submodule:01 sig:01 val:01 struct:01 val:01 mfg:98 abstract:01 caml-list:01 functions:01 writes:01 expression:02 expression:02 Thomas Braibant writes: > Hi list, > > Following on the thread "Subtyping structurally-equivalent records, or > something like it?", I made some experimentations with phantom types. > Unfortunately, I turns out that I do not understand the results I got. > > Could someone on the list explain why the first piece of code is well > typed, while the second one is not ? > > > type p1 > type p2 > > type 'a t = float > let x : p1 t = 0.0 > let id : p2 t -> p2 t = fun x -> x > let _ = id x (* type checks with type p2 t*) This is actualy a problem, at least for me. Because that is a type error you usualy want to specifically catch through the use of phantom types. But ocaml knows that 'a t = float and all floats are compatible. So it accepts all 'a t as the same. To make the phantom type checking work for you you need to move the definition of your phantom type into a submodule and make the type abstract through its signature. Any functions converting from one 'a t to 'b t also need to be in there. To avoid having to use the submodule name all the time you can use something like module M : sig type 'a t = private float val make : float -> 'a t end = struct type 'a t = float let make f = f end include M # let x : p1 t = make 0.0;; val x : p1 t = 0. # let id : p2 t -> p2 t = fun x -> x;; val id : p2 t -> p2 t = # let _ = id x;; Error: This expression has type p1 t = p1 M.t but an expression was expected of type p2 t = p2 M.t The "private" tells the type system that nobody (outside the module) is to create a value of that type. Only inside the module, where the type isn't private can you create one. > type 'a t = {l: float} > let x : p1 t = {l = 0.0} > let id : p2 t -> p2 t = fun x -> x > let _ = id x (* ill typed *) Why it works correctly here is explained nicely in the other mailss in this thread. > Any thoughts ? > > thomas MfG Goswin