2012-05-10 11 views
6

Digamos que tengo un módulo M parametrizado por un módulo F:Cómo definir una firma módulo cuya implementación del módulo está parametrizado por un funtor

module M (F : sig type id type data end) = 
struct 
type idtype = F.id 
type datatype = F.data 
type component = { id : idtype; data : datatype } 
let create id data = { id; data } 
let get_comp_data comp = comp.data 
let get_comp_id comp = comp.id 
end 

así que utilizar de esta manera:

module F1 = struct type id = int type data = float end 
module MF1 = M(F1) 

let comp = MF1.create 2 5.0 
let id = MF1.get_comp_id comp 

Ahora, si quiero M para que coincida con la firma S:

module type S = 
sig 
    type idtype 
    type datatype 
    type component 
    val create : idtype -> datatype -> component 
    val get_comp_data : component -> datatype 
    val get_comp_id : component -> idtype 
end 

module F1 = struct type id = int type data = float end 
module MF1 = (M(F1) : S) 

let comp = MF1.create 2 5.0 
let id = MF1.get_comp_id comp 

Lo que me molesta aquí es que, para definir get_comp_data y get_comp_id, necesito especificar idtype y datatype en el módulo S; Ahora solo imagine que tengo otros tipos de registros en M con sus propios tipos, tendré una docena de tipos para especificar en S? ¿Hay alguna forma más simple de evitar eso?

Respuesta

9

La forma natural de hacerlo es sellar el módulo en el sitio de definición, no en el sitio de uso. Entonces sólo tiene que expresar el intercambio de tipo una vez:

module M (F : sig type id type data end) : 
    S with type idtype = F.id and datatype = F.data 
    = struct ... end 

Si el parámetro funtor es más complejo que también puede simplemente comparten un módulo entero en lugar de tipos individuales. Por ejemplo:

module type TYPES = sig type id type data (* ...and more... *) end 

module type S = 
sig 
    module Types : TYPES 
    type component 
    val create : Types.id -> Types.data -> component 
    val get_comp_data : component -> Types.data 
    val get_comp_id : component -> Types.id 
end 

module M (F : TYPES) : S with module Types = F 
    = struct ... end 

O incluso se puede parametrizar la firma en sí, anidando en otro funtor:

module type TYPES = sig type id type data (* ...and more... *) end 

module S (F : TYPES) = 
struct 
    module type S = 
    sig 
    type component 
    val create : F.id -> F.data -> component 
    val get_comp_data : component -> F.data 
    val get_comp_id : component -> F.id 
    end 
end 

module M (F : TYPES) : S(F).S 
    = struct ... end 
+0

no sabe que puede colocar un módulo en otro módulo con el mismo nombre; asqueroso – codablank1

Cuestiones relacionadas