Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between module <name> = struct .. end and module type <name> = struct.. end?

Tags:

module

ocaml

module <name> =
   struct 
     .. 
   end;;


module type <name> =
    struct (* should have been sig *)
      .. 
end;;
like image 742
Zubeen Lalani Avatar asked Oct 28 '10 11:10

Zubeen Lalani


People also ask

What is a functor in OCaml?

What are functors and why do we need them? A functor is a module that is parametrized by another module, just like a function is a value which is parametrized by other values, the arguments. It allows one to parametrize a type by a value, which is not possible directly in OCaml without functors.

What is module in OCaml?

ocaml modules allow to package together data structures definitions and functions operating on them. This allow to reduce code size and name confusion, as any identifier can appear in different modules, with different meanings, without any interference.

What is an OCaml signature?

A signature specifies which components of a structure are accessible from the outside, and with which type. It can be used to hide some components of a structure (e.g. local function definitions) or export some components with a restricted type.


2 Answers

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
like image 155
Chris Conway Avatar answered Sep 28 '22 00:09

Chris Conway


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.

like image 43
Gilles 'SO- stop being evil' Avatar answered Sep 27 '22 23:09

Gilles 'SO- stop being evil'