Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Goswin von Brederlow <goswin-v-b@web.de>
To: Thomas Braibant <thomas.braibant@gmail.com>
Cc: caml-list@yquem.inria.fr
Subject: Re: [Caml-list] Phantom types
Date: Mon, 17 May 2010 18:37:22 +0200	[thread overview]
Message-ID: <87y6fiwkl9.fsf@frosties.localdomain> (raw)
In-Reply-To: <AANLkTilqG13QE_3iAcxHXMD99aBZk6HYceKkfN0W2EVT@mail.gmail.com> (Thomas Braibant's message of "Mon, 17 May 2010 16:59:52 +0200")

Thomas Braibant <thomas.braibant@gmail.com> 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 = <fun>
# 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


  parent reply	other threads:[~2010-05-17 16:37 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-17 14:59 Thomas Braibant
2010-05-17 15:14 ` [Caml-list] Phantom types [NC] Rabih CHAAR
2010-05-17 15:19   ` Philippe Veber
2010-05-17 16:00 ` Phantom types Dawid Toton
2010-05-17 16:37 ` Goswin von Brederlow [this message]
  -- strict thread matches above, loose matches on Subject: below --
2004-07-31  8:56 [Caml-list] const equivalent for mutable types? Christopher A. Gorski
2004-07-31 10:34 ` Markus Mottl
2004-07-31 13:44   ` Jon Harrop
2004-07-31 16:31     ` [Caml-list] Phantom types Markus Mottl
2004-08-23  9:49       ` Jon Harrop
2004-08-23 15:16         ` Jon Harrop
2004-08-27  9:03           ` Jacques GARRIGUE
2004-08-25 21:03         ` brogoff

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87y6fiwkl9.fsf@frosties.localdomain \
    --to=goswin-v-b@web.de \
    --cc=caml-list@yquem.inria.fr \
    --cc=thomas.braibant@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox