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


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

¿Usted intentó compilar su 'tipo de módulo Nombre = struct ... end' antes de pedir? –

+0

Sólo quería ilustrar un ejemplo. Yo estaba trabajando en un módulo grande y se dio cuenta de que no me quería distraer a la gente de la cuestión real. –

Respuesta

7

El primero declara un módulo y el segundo declara un tipo de módulo (también conocido como firma). Un tipo de módulo contiene type y val declaraciones, mientras que un módulo puede contener definiciones (por ejemplo, enlaces let). Puede usar una firma para restringir el tipo de un módulo, al igual que lo haría para una función. Por ejemplo,

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

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

Ahora, tenemos

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

M.g no está consolidado porque está oculto por la firma T.

Otra forma común de usar tipos de módulos es como argumentos y valores de retorno de los funtores. Por ejemplo, el Map.Make funtor en the standard library lleva un módulo con la firma Map.OrderedType y crea un módulo con la firma Map.S

P. S. Tenga en cuenta que hay un error en la pregunta. Un tipo de módulo se declara utilizando

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

tipo de módulo describe un módulo. Es lo mismo que la diferencia entre .ml y .mli

3

A estructura (escrito struct … end) es un manojo de definiciones. Cualquier objeto en el lenguaje puede definirse en un módulo: valores centrales (let x = 2 + 2), tipos (type t = int), módulos (module Empty = struct end), firmas (module type EMPTY = sig end), etc. Los módulos son una generalización de estructuras: una estructura es un módulo, y también lo es un functor (piénselo como una función que toma un módulo como argumento y devuelve un nuevo módulo). Los módulos son como valores centrales, pero viven en un nivel superior: un módulo puede contener cualquier cosa, mientras que un valor central solo puede contener otros valores centrales¹.

Un firma (escrito) es un grupo de especificaciones (algunos idiomas utilizan el término declaración). Cualquier objeto en el lenguaje puede ser especificado en un módulo: valores básicos (val x : int), los tipos (type t = int), módulos (module Empty : sig end), firmas (module type EMPTY = sig end), etc. tipos de módulo generalizan firmas: un tipo de módulo especifica un módulo, y un tipo de módulo que ocurre para especificar una estructura se llama firma. Los tipos de módulos son para los módulos de lo que los tipos ordinarios son para los valores centrales.

Las unidades de compilación (.ml archivos) son estructuras. Las interfaces (.mli archivos) son firmas.

Así que module Foo = struct … end define un módulo llamado Foo, que resulta ser una estructura. Esto es análogo a let foo = (1, "a") que define un valor llamado foo que resulta ser un par. Y module type FOO = sig … end (nota: sig, no struct) define un tipo de módulo llamado FOO, que resulta ser una firma.Esto es análogo a type foo = int * string que define un tipo llamado foo que pasa a ser un tipo de producto.

¹ Esto de hecho ya no es cierto ya que OCaml 3.12 introdujo los módulos de primera clase, pero está lo suficientemente cerca para una presentación introductoria.

Cuestiones relacionadas