2009-03-12 19 views
12

Estoy teniendo un problema con un funtor (y su tipo resultante). A continuación, tengo un functor Set que usa un tipo ordenado. De hecho, utilicé el set.ml que viene con ocaml como guía, pero parece que estoy haciendo todo ahhem derecho. Creé un módulo Ordenado con enteros y lo apliqué al Set functor para obtener el último módulo en este ejemplo de código, IntSet.Functors en Ocaml

La próxima línea falla, cuando intento insertar un número entero. Aparece el siguiente tipo de error:

Error: This expression has type int but is here used with type 
     SetInt.elt = Set(OrdInt).elt 

No me malinterprete, el sistema de tipos es el correcto aquí. El nivel superior informa que el tipo de SetInt.elt es Set(OrdInt).elt, pero cuando hago las mismas operaciones para configurar un Set utilizando el proporcionado por ocaml, la 'misma' línea es SetInt.elt = OrderedInt.t. Parece que debería estar recibiendo SetInt.elt = Ordered.t.

¡Esto es tan simple, probablemente me estoy perdiendo un detalle estúpido! argh!

Tenga en cuenta: He simplificado las funciones de miembro/insertar aquí ya que este problema tiene que ver con los tipos.

module type Ordered = 
    sig 
    type t 
    val lt : t -> t -> bool 
    val eq : t -> t -> bool 
    val leq : t -> t -> bool 
    end 

module type S = 
    sig 
    type elt 
    type t 
    exception Already_Exists 
    val empty : t 
    val insert : elt -> t -> t 
    val member : elt -> t -> bool 
    end 

module Set (Elt:Ordered) : S = 
    struct 
    type elt = Elt.t 
    type t = Leaf | Node of t * elt * t 
    exception Already_Exists 
    let empty = Leaf 
    let insert e t = t 
    let member e t = false 
    end 

module OrdInt : Ordered = 
    struct 
    type t = int 
    let lt a b = a < b 
    let eq a b = a = b 
    let leq a b = a <= b 
    end 

module IntSet = Set (OrdInt) 

(* line that fails *) 
let one_elm = IntSet.insert 1 IntSet.empty 

Respuesta

14

es necesario cambiar estas dos líneas

module Set (Elt:Ordered) : S = 
module OrdInt : Ordered = 

a

module Set (Elt:Ordered) : S with type elt = Elt.t = 
module OrdInt : Ordered with type t = int = 

Sin éstos, los módulos no tienen firmas que exponen los tipos elt yt como int.

[Editar]: El set.ml no tiene el bit 'con', porque hay un sml.mli, que declara la firma para el funtor y tiene el 'con'. Además, OrdInt no necesita 'con' si no se especifica explícitamente una firma para que, de esta manera:

module OrdInt = 

También puede construir el conjunto al definir el módulo en su lugar:

module IntSet = Set (struct 
type t = int 
let lt a b = a < b 
let eq a b = a = b 
let leq a b = a <= b 
end)