tags:

views:

33

answers:

3
module <name> =
   struct 
     .. 
   end;;


module type <name> =
    struct (* should have been sig *)
      .. 
end;;
A: 

module type describe a module. It is the same as the difference between .ml and .mli

Zubeen Lalani
+5  A: 

The first declares a module and the second declares a module type (aka a signature). A module type contains type and val declarations, whereas a module can contain definitions (e.g., let bindings). You can use a signature to restrict the type of a module, much as you might for a function. For example,

module type T = sig
  val f : int -> int
end

module M : T = struct
  let f x = x + 1
  let g x = 2 * x
end

Now, we have

# M.f 0 ;;
- : int = 1
# M.g 0 ;;
Error: Unbound value M.g

M.g is unbound because it's hidden by the signature T.

Another common way to use module types is as arguments to and return values of functors. For example, the Map.Make functor in the standard library takes a module with signature Map.OrderedType and creates a module with signature Map.S

P.S. Note that there's a mistake in the question. A module type is declared using

module type <name> = sig
  ...
end
Chris Conway
+2  A: 

A structure (written struct … end) is a bunch of definitions. Any object in the language can be defined in a module: core values (let x = 2 + 2), types (type t = int), modules (module Empty = struct end), signatures (module type EMPTY = sig end), etc. Modules are a generalization of structures: a structure is a module, and so is a functor (think of it as a function that takes a module as argument and returns a new module). Modules are like core values, but live one level above: a module can contain anything, whereas a core value can only contain other core values¹.

A signature (written sig … end) is a bunch of specifications (some languages use the term declaration). Any object in the language can be specified in a module: core values (val x : int), types (type t = int), modules (module Empty : sig end), signatures (module type EMPTY = sig end), etc. Module types generalize signatures: a module type specifies a module, and a module type that happens to specify a structure is called a signature. Module types are to modules what ordinary types are to core values.

Compilation units (.ml files) are structures. Interfaces (.mli files) are signatures.

So module Foo = struct … end defines a module called Foo, which happens to be a structure. This is analogous to let foo = (1, "a") which defines a value called foo which happens to be a pair. And module type FOO = sig … end (note: sig, not struct) defines a module type called FOO, which happens to be a signature. This is analogous to type foo = int * string which defines a type called foo which happens to be a product type.

¹ This is in fact no longer true since OCaml 3.12 introduced first-class modules, but it's close enough for an introductory presentation.

Gilles