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-21 (09:56)
From: Matt Armstrong <matt@l...>
Subject: Re: Is this interface a good idea?
Remi VANICAT <vanicat+egroups@l...> writes:

> Matt Armstrong <matt@l...> writes:

[...]

>> However, I noticed that when you make a ('a, 'b) path equivalent to
>> string, it is type safe only outside the module. Inside the
>> module, the type equivalence (effectively implicit conversion
>> between the two types) allows for unintended errors. So I prefer
>> 
>> type ('a, 'b) path = Path of string
>> 
>> even within the module. It makes converting between the two types
>> explicit, so this beginner will make fewer mistakes. Perhaps when
>> I get more comfortable with ocaml I will switch, but for now my way
>> seems less magical. :-)
>
> Not sure it change most things...

Are you saying you are not sure if it changes things within the
module? I found that it did with this code in a .ml:

======================================================================
type directory
type file
type absolute
type relative
type ('a,'b) path = string

let id x = x
let parse_relative_dir : string -> (relative, directory) path = id
let parse_relative_file : string -> (relative, file) path = id
let parse_absolute_dir : string -> (absolute, directory) path = id
let parse_absolute_file : string -> (absolute, file) path = id
let concat : ('a, directory) path -> (relative, 'b) path -> ('a, 'b) path =
( ^ )
let path_to_string : ('a, 'b) path -> string = id;;

let rd = parse_relative_dir("relative dir")
and ad = parse_absolute_dir("absolute dir")
in 
print_endline (path_to_string (concat rd ad))
======================================================================

Notice that (concat rd ad) is allowed, despite ad not matching
(relative, 'b) path. Presumably because *within* this module, ('a,'b)
path is a string, so none of the desired typing is taking place. I
could probably even do ("/etc/" ^ parse_absolute_file("/etc/hosts"))
which is clearly wrong.

But with the following implementation, the type checker finds the
error. This is why I will reserve using type abbreviations (like
above) for making type names shorter only.

======================================================================
type directory
type file
type absolute
type relative
type ('a,'b) path = Path of string

let parse_relative_dir : string -> (relative, directory) path =
fun s -> Path s
let parse_relative_file : string -> (relative, file) path =
fun s -> Path s
let parse_absolute_dir : string -> (absolute, directory) path =
fun s -> Path s
let parse_absolute_file : string -> (absolute, file) path =
fun s -> Path s
let concat : ('a, directory) path -> (relative, 'b) path -> ('a, 'b) path =
fun (Path s1) (Path s2) -> Path(s1 ^ s2)
let path_to_string : ('a, 'b) path -> string =
fun (Path s) -> s;;

let rd = parse_relative_dir("relative dir")
and ad = parse_absolute_dir("absolute dir")
in 
print_endline (path_to_string (concat rd ad))
======================================================================