On Sun, May 27, 2007 at 06:04:00AM -0000, roparzhhemon wrote:
> Just how do you implement this "private datatype" in OCaml ? E.g, for
> seconds, one could write
>
> type number_of_seconds=Sec0 |Sec1 |Sec2 |Sec3 (...) |Sec59;;
>
> Is this good or bad practice in OCaml (will the compiler take
> more time to understand and use that "(too?) long enumeration" sort
> of data) ?
Actually OCaml will represent it internally as an integer, 0, 1, 2 ... 59.
However such a datatype has lots of drawbacks - for example how do you
go forwards by 1 second? One way is to write a very long function:
let next = function
| Sec0 -> Sec1
| Sec1 -> Sec2
| etc.
The machine code implementation of this will be very inefficient. And
what if you want to go forwards 3 seconds?
A hidden data type has the same representation (integer) but allows
you to write the operations efficiently. Just have two files:
----- secs.mli -----
type t (* in public this is hidden *)
val make : int -> t
val next : t -> t
val add : t -> int -> t
val get : t -> int
----- secs.ml ------
type t = int (* the real representation *)
let make i = assert (i >= 0 && i < 60); i
let next s =
let i = s + 1 in
if i < 60 then i else 0
let add s i = (s + i) mod 60
let get s = s
Note that the implementation constrains the integer to the range 0-59 [*].
Then other code can do for example:
----- test.ml -----
let secs = Secs.make 59 ;;
let secs = Secs.next secs ;;
Printf.printf "secs = %dn" (Secs.get secs);;
Compile this with:
ocamlc -c secs.mli
ocamlc -c secs.ml
ocamlc -c test.ml
ocamlc -o test secs.cmo test.cmo
and run it:
./test
secs = 0
> Another related question : suppose I'm creating an OCaml library,
> and I have a type int_set that is in fact an int list, but I don't want the
> end user to know how it's implemented.
> If I just write type t=int list in file "int_set.ml", the end user only
> has to write "module X=Int_set;;" in the toplevel to learn that
> Int_set.t is simply int list. Is there a way to hide the implementation ?
Use a signature, in a separate file, as above.
Rich.
[*] Real time implementations typically constrain seconds to the range
0 - 60, in order to represent leap seconds. This is why you should
use a pre-built library, rather than rolling your own code.
--
Richard Jones
Red Hat
.