List Info

Thread: Re: "ocaml_beginners"::[] type constructors again




Re: "ocaml_beginners"::[] type constructors again
country flaguser name
United States
2007-05-27 01:04:00

--- In ocaml_beginners%40yahoogroups.com">ocaml_beginnersyahoogroups.com, micha <micha-1...> wrote:
&gt;
>
> you can make the datatype private, so values of it can only be created
> with your functions, but pattern matching works.
&gt;

Just how do you implement this "private datatype&quot; 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) ?

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 ?

Ewan

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] type constructors again
country flaguser name
United Kingdom
2007-05-27 01:26:49

On Sunday 27 May 2007 07:04:00 roparzhhemon wrote:
&gt; Just how do you implement this "private datatype&quot; in OCaml ?

# type t = private A;;
type t = private A

>; E.g, for seconds, one could write
&gt;
> type number_of_seconds=Sec0 |Sec1 |Sec2 |Sec3 (...) |Sec59;;
>
>; Is this good or bad practice in OCaml

In OCaml, the objective is to write as little code as possible. The above
example requires you to write out lots of constructors by hand.

A shorter way is:

type secs = Sec of int

&gt; 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 ?

Yes indeed. If you consider your module written with a full interface (you can
get this by compiling the module structure with -i to get the inferred
signature):

module A : sig
type t = int list
end = struct
type t = int list
end

All you do is leave off the definition of the type in the signature and it is
abstracted away:

module A : sig
type t
end = struct
type t = int list
end

Everything outside the module A is then unaware that A.t is actually an int
list.

--
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
The F#.NET Journal
http://www.ffconsultancy.com/products/fsharp_journal/?e

__._,_.___
.

__,_._,___
Re: "ocaml_beginners"::[] type constructors again
country flaguser name
United Kingdom
2007-05-27 04:21:55

On Sun, May 27, 2007 at 06:04:00AM -0000, roparzhhemon wrote:
&gt; Just how do you implement this "private datatype&quot; in OCaml ? E.g, for
> seconds, one could write
&gt;
> 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

__._,_.___
.

__,_._,___
[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )