On Fri, 5 Jan 2007, brogoff wrote: > On Fri, 5 Jan 2007, Nathaniel Gray wrote: >> On 12/29/06, Mattias Engdegård wrote: >>> Is there a reason for this? To my innocent eyes, code like >>> >>> type length = Length of int >>> >>> looks quite reasonable and could be useful at times. >> >> I agree. Sadly, the ocaml devs don't. >> >> http://caml.inria.fr/mantis/view.php?id=3978 >> >> As Xavier points out, one can use modules to hide basic types, but >> this is pretty clumsy in practice. There's rumored to be a solution >> using phantom types, but my attempts don't work: > > You need to use modules to make phantom types work. Something like this > > module type BOINK = > sig > type 'a t > val inj : int -> 'a t > val prj : 'a t -> int > val plus : 'a t -> 'a t -> 'a t > end;; > > module Boink : BOINK = > struct > type 'a t = int > let inj n = n > let prj t = t > let plus x y = x + y > end;; > > let f : string Boink.t = inj 20;; > let g : int Boink.t = inj 30;; > > Boink.plus f g;; > > I didn't compile that, but you get the idea... In case anyone finds it useful, I have this code which is ready to use (copy the files it into your project): http://martin.jambon.free.fr/ocaml.html#opaque It works only for strings and ints. You can write: open Opaque let x : [`Year] int_t = int_t 2007 let next_year x : [`Year] int_t = int_t (t_int x + 1) It gives you: val x : [ `Year ] Opaque.int_t val next_year : 'a Opaque.int_t -> [ `Year ] Opaque.int_t Note that we need one more type annotation if we want to get the following signature: val next_year : [ `Year ] Opaque.int_t -> [ `Year ] Opaque.int_t or we can just use "successor" which is equivalent to "succ": val successor : 'a Opaque.int_t -> 'a Opaque.int_t As you can see, things can get pretty ugly, but I found this technique useful to avoid confusion between identifiers that identify different types of objects. Not in my average "hello world" script. Martin -- Martin Jambon http://martin.jambon.free.fr