2010-07-25 15 views
8

Sono abbastanza bloccato con il seguente problema di functor in OCaml. Incollo parte del codice solo per farti capire. FondamentalmenteComprensione dei funtori in OCaml

Ho definito questi due moduli in pctl.ml:

module type ProbPA = sig 
    include Hashtbl.HashedType 
    val next: t -> (t * float) list 
    val print: t -> float -> unit 
end 

module type M = sig 
    type s 
    val set_error: float -> unit 
    val check: s -> formula -> bool 
    val check_path: s -> path_formula -> float 
    val check_suite: s -> suite -> unit 
end 

e la seguente funtore:

module Make(P: ProbPA): (M with type s = P.t) = struct 
    type s = P.t 
    (* implementation *) 
end 

Poi utilizzare effettivamente questi moduli ho definito un nuovo modulo direttamente in un file denominato prism.ml:

type state = value array 
type t = state 
type value = 
    | VBOOL of bool 
    | VINT of int 
    | VFLOAT of float 
    | VUNSET 
(* all the functions required *) 

Da una terza fonte (formulas.ml) Ho usato il funtore con Prism modulo:

module PrismPctl = Pctl.Make(Prism) 
open PrismPctl 

E infine dal main.ml

open Formulas.PrismPctl 
(* code to prepare the object *) 
PrismPctl.check_suite s.sys_state suite (* error here *) 

e compila dà il seguente errore

Error: This expression has type Prism.state = Prism.value array but an expression was expected of type Formulas.PrismPctl.s

Da quello che posso capire che ci una sorta di cattivo aliasing dei nomi, sono gli stessi (dal value array è il tipo definito come t e viene utilizzato M with type s = P.t nel functor) ma il controllo di tipo non li considera uguali.

Davvero non capisco dov'è il problema, qualcuno può aiutarmi?

Grazie in anticipo

+0

Non so abbastanza di OCaml per aiutare, ma è possibile che questa domanda precedente è un problema simile? http://stackoverflow.com/questions/640510/functors-in-ocaml – Gian

+0

@Gian: è lo stesso problema di root, ma se lo capisci, sei già sulla buona strada per non aver bisogno di porre la domanda nel primo posto. – Gilles

risposta

6

(Si pubblica codice non compilabile. Questa è una cattiva idea perché potrebbe rendere più difficile per le persone aiutarti, e perché ridurre il problema a un semplice esempio è a volte sufficiente per risolverlo. Ma penso di vedere comunque la tua difficoltà)

All'interno di formulas.ml, Ocaml può vedere che PrismPctl.s = Pctl.Make(Prism).t = Prism.t; la prima uguaglianza deriva dalla definizione di PrismPctl e la seconda uguaglianza deriva dalla firma di Pctl.Make (in particolare il numero with type s = P.t).

Se non si scrive un file mli per Formulas, il codice deve essere compilato. Quindi il problema deve essere che il file che hai scritto non menzioni la giusta uguaglianza.Non mostrare i file .mli (si dovrebbe, sono parte del problema), ma presumibilmente hai scritto

module PrismPctl : Pctl.M 

questo non basta: quando il compilatore compila main.ml, non si sa nulla di PrismPctl non è specificato in formulas.mli. È necessario specificare

module PrismPctl : Pctl.M with type s = Prism.t 

o, supponendo che si incluso with type s = P.t nella firma di Make in pctl.mli

module PrismPctl : Pctl.M with type s = Pctl.Make(Prism).s 
+0

Questo era il problema. L'ho capito ieri osservando la risposta dare sulla domanda collegata da gian all'interno del commento. Non ho incollato il mio file '.mli' perché ho dimenticato di farlo .. colpa mia! Grazie – Jack

2

Questo è un problema che ho incontrato pure quando si impara di più su questi. Quando crei il functor esponi la firma del functor, in questo caso M. Contiene un tipo astratto s, parametrizzato dal funtore e qualsiasi cosa più specifica non è esposta all'esterno. Pertanto, l'accesso a qualsiasi elemento del record di s (come in sys_state) provocherà un errore di tipo, come si è verificato.

Il resto sembra a posto. È decisamente difficile entrare nell'uso dei funtori correttamente, ma ricorda che puoi solo manipolare le istanze del tipo parametrizzato dal functor attraverso l'interfaccia/firma che viene esposta dal functor.