2010-10-28 2 views
6
module <name> = 
    struct 
    .. 
    end;; 


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

Avez-vous essayé de compiler votre 'type de module Name = struct ... end' avant de demander? –

+0

Je voulais juste illustrer un exemple. Je travaillais sur un gros module et j'ai réalisé que je ne voulais pas distraire les gens de la question. –

Répondre

7

Le premier déclare un module et le second déclare un type de module (aka une signature). Un type de module contient les déclarations type et val, tandis qu'un module peut contenir des définitions (par exemple, let liaisons). Vous pouvez utiliser une signature pour restreindre le type d'un module, comme vous le feriez pour une fonction. Par exemple,

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

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

Maintenant, nous avons

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

M.g est non liée, car il est caché par la signature T.

Une autre façon courante d'utiliser des types de modules est d'utiliser des arguments et de renvoyer des valeurs de foncteurs. Par exemple, le foncteur Map.Make dans the standard library prend un module avec la signature Map.OrderedType et crée un module avec la signature Map.S

post-scriptum Notez qu'il y a une erreur dans la question. Un type de module est déclarée à l'aide

module type <name> = sig 
    ... 
end 
0

Le type de module décrit un module. C'est la même chose que la différence entre .ml et .mli

3

Structure (écrit struct … end) est un ensemble de définitions . Tout objet dans la langue peut être défini dans un module: valeurs fondamentales (let x = 2 + 2), types (type t = int), modules (module Empty = struct end), signatures (module type EMPTY = sig end), etc. Les modules sont une généralisation de structures: une structure est un module, Il en est de même pour un foncteur (considérez-le comme une fonction qui prend un module comme argument et renvoie un nouveau module). Les modules sont comme des valeurs de base, mais vivent à un niveau supérieur: un module peut contenir n'importe quoi, alors qu'une valeur de base ne peut contenir que d'autres valeurs de base¹.

Une signature (écrit) est un groupe de spécifications (certaines langues utilisent le terme déclaration). Tout objet dans la langue peut être spécifiée dans un module: valeurs de base (val x : int), types (type t = int), les modules (module Empty : sig end), signatures (module type EMPTY = sig end), etc. types de modules généralisent signatures: un type de module spécifie un module et un type de module qui arrive à spécifier une structure est appelé une signature. Les types de module sont des modules ce que les types ordinaires sont aux valeurs fondamentales.

Les unités de compilation (fichiers .ml) sont des structures. Les interfaces (.mli fichiers) sont des signatures.

Donc module Foo = struct … end définit un module appelé Foo, qui se trouve être une structure. Ceci est analogue à let foo = (1, "a") qui définit une valeur appelée foo qui se trouve être une paire. Et module type FOO = sig … end (note: sig, pas struct) définit un type de module appelé FOO, qui se trouve être une signature.Ceci est analogue à type foo = int * string qui définit un type appelé foo qui se trouve être un type de produit.

¹ Ceci n'est plus vrai puisque OCaml 3.12 a introduit des modules de première classe, mais il est assez proche pour une présentation d'introduction.

Questions connexes