Browse thread
Question on writing efficient Ocaml.
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Nathaniel Gray <n8gray@g...> |
| Subject: | Re: [Caml-list] Question on writing efficient Ocaml. |
Thanks to everybody for the discussion of phantom types. I guess modules are unavoidable then. Too bad... :^( On 1/5/07, Martin Jambon <martin.jambon@ens-lyon.org> wrote: > On Fri, 5 Jan 2007, brogoff wrote: > > > On Fri, 5 Jan 2007, Nathaniel Gray wrote: > >> On 12/29/06, Mattias Engdegård <mattias@virtutech.se> 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 > -- >>>-- Nathaniel Gray -- Caltech Computer Science ------> >>>-- Mojave Project -- http://mojave.cs.caltech.edu -->