Version française
Home     About     Download     Resources     Contact us    
Browse thread
Question on writing efficient Ocaml.
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ 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 -->