2010-07-25 30 views
8

Estoy bastante atrapado con el siguiente problema de functor en OCaml. Pego algo del código solo para que entiendas. BásicamenteEntender los funtores en OCaml

que definen estos dos módulos en 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 

y la siguiente funtor:

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

Luego de utilizar realmente estos módulos he definido un nuevo módulo directamente en un archivo llamado 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 *) 

De una tercera fuente (formulas.ml) que utiliza el funtor con Prism módulo:

module PrismPctl = Pctl.Make(Prism) 
open PrismPctl 

Y finalmente, desde main.ml

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

y compila da el siguiente error

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

De lo que puedo entender que hay una especie de mal aliasing de los nombres, son los mismos (ya que value array es el tipo definido como t y usó M with type s = P.t en el funtor) pero el verificador de tipos no los considera iguales.

Realmente no entiendo dónde está el problema, ¿alguien puede ayudarme?

Gracias de antemano

+0

No sé lo suficiente sobre OCaml para ayudar, pero es posible que esta pregunta anterior es un problema similar? http://stackoverflow.com/questions/640510/functors-in-ocaml – Gian

+0

@Gian: es el mismo problema de raíz, pero si comprende eso, ya está en camino a no necesitar hacer la pregunta en el primer lugar. – Gilles

Respuesta

6

(Publicas código no compilable. Es una mala idea porque puede dificultar que las personas te ayuden, y porque reducir tu problema a un simple ejemplo a veces es suficiente para resolverlo. Pero creo que veo su dificultad de todos modos.)

Dentro de formulas.ml, Ocaml puede ver que PrismPctl.s = Pctl.Make(Prism).t = Prism.t; la primera igualdad es de la definición de PrismPctl, y la segunda igualdad es de la firma de Pctl.Make (específicamente el bit with type s = P.t).

Si no escribe un archivo mli para Formulas, debe compilar su código. Entonces, el problema debe ser que el archivo .mli que escribió no menciona la igualdad correcta.No muestras tus .mli archivos (que debe, que son parte del problema), pero se supone que escribió

module PrismPctl : Pctl.M 

eso no es suficiente: cuando el compilador compila main.ml, no se sabe nada de PrismPctl eso no está especificado en formulas.mli. Es necesario especificar ya sea

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

o, suponiendo que haya incluido with type s = P.t en la firma de Make en pctl.mli

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

Ese era el problema. Me di cuenta ayer al mirar la respuesta dada en la pregunta vinculada por gian dentro del comentario. No pegué mi archivo '.mli' porque olvidé hacerlo ... ¡es culpa mía! Gracias – Jack

2

Este es un problema me encontré así al aprender más acerca de estos. Cuando crea el functor, expone la firma del functor, en este caso M. Contiene un tipo abstracto s, parametrizado por el funtor, y cualquier elemento más específico no está expuesto al exterior. Por lo tanto, acceder a cualquier elemento de registro de s (como en sys_state) dará como resultado un error de tipo, como el que ha encontrado.

El resto se ve bien. Definitivamente es difícil utilizar funtores correctamente, pero recuerde que solo puede manipular instancias del tipo parametrizado por el funtor a través de la interfaz/firma expuesta por el funtor.