Functors a Ocaml
-
11-07-2019 - |
Domanda
Sto riscontrando un po 'di problemi con un functor (ed è il tipo risultante). Di seguito, ho una funzione Set che utilizza un tipo Ordinato. In realtà ho usato il set.ml
fornito con ocaml come guida, ma sembra che stia facendo tutto ahhem nel modo giusto. Ho creato un modulo ordinato con numeri interi e l'ho applicato al set funzione per ottenere l'ultimo modulo su questo esempio di codice, IntSet.
La riga successiva non riesce, quando provo a inserire un numero intero. Ottengo il seguente errore di tipo:
Error: This expression has type int but is here used with type
SetInt.elt = Set(OrdInt).elt
Non fraintendetemi, il sistema dei tipi è corretto qui. Il livello superiore riporta che il tipo di SetInt.elt
è Set (OrdInt) .elt
, ma quando eseguo le stesse operazioni per impostare un set usando quello fornito per ocaml la 'stessa' riga è SetInt.elt = OrderedInt.t
. Sembra che dovrei ottenere SetInt.elt = Ordered.t
.
Questo è così semplice, probabilmente mi manca solo qualche dettaglio stupido! Argh!
Nota: ho semplificato le funzioni member / insert qui poiché questo problema ha a che fare con i tipi.
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
Soluzione
Devi cambiare queste due righe
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 =
Senza questi, i moduli non avranno firme che espongono i tipi elt et int come
[Modifica]: Set.ml non ha il bit 'with', perché c'è un sml.mli, che dichiara la firma per il functor e ha 'with'. Inoltre, OrdInt non ha bisogno di "with" se non si specifica esplicitamente una firma per questo, in questo modo:
module OrdInt =
Puoi anche costruire il set definendo il modulo sul posto:
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)