Lukasz Madon
Lukasz Madon

Reputation: 14994

Type declaration with and

What is benefit of type declaration:

type xxx
and yyy

over

type xxx
type yyy

To give it semantic that one depends on another?

I'm using OcamlWin 4.0 and the code is from C:\OCaml\lib\hashtbl.ml

  type ('a, 'b) t =
  { mutable size: int;                        (* number of entries *)
    mutable data: ('a, 'b) bucketlist array;  (* the buckets *)
    mutable seed: int;                        (* for randomization *)
    initial_size: int;                        (* initial array size *)
  }

and ('a, 'b) bucketlist =
    Empty
  | Cons of 'a * 'b * ('a, 'b) bucketlist

it compiles. When I change the and to type

type ('a, 'b) t =
  { mutable size: int;                        (* number of entries *)
    mutable data: ('a, 'b) bucketlist array;  (* the buckets *)
    mutable seed: int;                        (* for randomization *)
    initial_size: int;                        (* initial array size *)
  }

type ('a, 'b) bucketlist =
    Empty
  | Cons of 'a * 'b * ('a, 'b) bucketlist

compiles as well.

Upvotes: 0

Views: 93

Answers (2)

Jesper.Reenberg
Jesper.Reenberg

Reputation: 5944

The and keyword is often used when defining mutually recursive declarations

Given your example

type ('a, 'b) t =
    { mutable size: int;                        (* number of entries *)
      mutable data: ('a, 'b) bucketlist array;  (* the buckets *)
      mutable seed: int;                        (* for randomization *)
      initial_size: int;                        (* initial array size *)
    }

type ('a, 'b) bucketlist =
    Empty
  | Cons of 'a * 'b * ('a, 'b) bucketlist

would give an Error: Unbound type constructor bucketlist on line 3, characters 20-39. However changing the second type with an and will remove the error.

type ('a, 'b) t =
    { mutable size: int;                        (* number of entries *)
      mutable data: ('a, 'b) bucketlist array;  (* the buckets *)
      mutable seed: int;                        (* for randomization *)
      initial_size: int;                        (* initial array size *)
    }

and ('a, 'b) bucketlist =
    Empty
  | Cons of 'a * 'b * ('a, 'b) bucketlist

I can't come up with a reason why it would compile for you in both cases, however if you were using the interpreter and you forget to close it down, then it will have old bindings in its environment.
That is, if you have first evaluated you code with the and keyword then you can keep re-evaluating the code without as bucketlist have already been defined in the invironment.

Upvotes: 3

Andreas Rossberg
Andreas Rossberg

Reputation: 36078

The and keyword is needed to express mutually recursive definitions. For example,

type t = A | B of u
and  u = C | D of t

would no longer compile if you were to replace and with type. In your example, its use is redundant, though.

Upvotes: 2

Related Questions