Version française
Home     About     Download     Resources     Contact us    

This site is updated infrequently. For up-to-date information, please visit the new OCaml website at ocaml.org.

Browse thread
Is this interface a good idea?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: 2002-05-20 (07:24)
From: Remi VANICAT <vanicat+egroups@l...>
Subject: Re: "ocaml_beginners"::[] Is this interface a good idea?
Matt Armstrong <matt@l...> writes:

> As my first "real" OCaml module, I want to produce a filename module
> that will type the different kinds of filename components and only
> allow me to combine them in the correct way. E.g.
>
> concat AbsolutePath("/tmp") RelativeFile("foo")
>
> Yields "/tmp/foo" which is good, but
>
> concat AbsolutePath("/tmp") AbsoluteFile("/etc/hosts")
>
> Yields "/tmp//etc/hosts" which is bad and should be prevented by the
> type checker.
>
> So I formulated four different kinds of pathnames and came up with an
> interface for them (incomplete, but useful). But the result is a bit
> unwieldy and certainly less convenient than just dealing with strings
> directly (as the standard OCaml Filename module does).
>
> Are there any OCaml tricks I can employ here? E.g. it'd be nice to
> get rid of the four concat_XX_YY functions in favor of a single
> function. Same with the four XX_to_string functions. Is there any
> way I can do this without resorting to type checking at runtime?

yes, phantom type can be the solution :

(* file.mli *)

type ('a, 'b) file_or_dir

val parse_relative_dir : string -> ([ `Relative ], [ `Dir ]) file_or_dir
val parse_relative_file : string -> ([ `Relative ], [ `File ]) file_or_dir
val parse_absolute_dir : string -> ([ `Absolute ], [ `Dir ]) file_or_dir
val parse_absolute_file : string -> ([ `Absolute ], [ `File ])file_or_dir
val concat : ('a,[> `Dir]) file_or_dir ->
([> `Relative],'b) file_or_dir -> ('a,'b) file_or_dir
val file_or_dir_to_string : ('a, 'b) file_or_dir -> string

(* file.ml *)

type ('a, 'b) file_or_dir = string

let parse_relative_dir st = st
let parse_relative_file st = st
let parse_absolute_dir st = st 
let parse_absolute_file st = st
let concat st1 st2 = st1 ^ st2
let file_or_dir_to_string st = st



there is a very interesting article about phatom type at : 
http://caml.inria.fr/archives/200109/msg00097.html
or
http://groups.google.com/groups?hl=fr&lr=&safe=off&threadm=fa.h7b207v.11hor9l%40ifi.uio.no&rnum=2&prev=/groups%3Fq%3Dphantom%2Btype%2Bocaml%26hl%3Dfr%26lr%3D%26safe%3Doff%26selm%3Dfa.h7b207v.11hor9l%2540ifi.uio.no%26rnum%3D2
(it's the same)

-- 
Rémi Vanicat
vanicat@l...
http://dept-info.labri.u-bordeaux.fr/~vanicat