Question

J'ai un petit problème avec un foncteur (et le type qui en résulte). Ci-dessous, j'ai un foncteur Set qui utilise un type Ordered. En fait, j’ai utilisé le code set.ml fourni avec ocaml à des fins d’aide, mais il semble que je fasse tout ce qu’il faut ahhem . J'ai créé un module Ordered avec des entiers et je l'ai appliqué au foncteur Set pour obtenir le dernier module de cet exemple de code, IntSet.

La ligne suivante échoue lorsque j'essaie d'insérer un entier. Je reçois le type d'erreur suivant:

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

Ne vous méprenez pas, le système de types est correct ici. Le niveau supérieur indique que le type de SetInt.elt est Set (OrdInt) .elt , mais lorsque je fais les mêmes opérations pour configurer un Set à l'aide de celui fourni. par ocaml, la même ligne est SetInt.elt = OrderedInt.t . On dirait que je devrais recevoir SetInt.elt = Ordered.t .

C’est si simple, il me manque probablement quelques détails stupides! argh!

Remarque: j'ai simplifié les fonctions membre / insertion ici car ce problème concerne les types.

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
Était-ce utile?

La solution

Vous devez changer ces deux lignes

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

à

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

Sans cela, les modules n'auront pas de signatures exposant les types elt et t as int.

[Modifier]: Le fichier set.ml n'a pas le bit 'with', car il existe un sml.mli, qui déclare la signature du foncteur et qui possède le 'with'. De plus, OrdInt n'a pas besoin de 'avec' si vous ne spécifiez pas explicitement de signature, comme ceci:

module OrdInt =

Vous pouvez également construire l'ensemble en définissant le module en place:

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) 
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top