He tropezado con un problema OCaml bastante simple, pero parece que no puedo encontrar una solución elegante. Estoy trabajando con funtores que se aplican a módulos relativamente simples (generalmente definen un tipo y algunas funciones en ese tipo) y extienden esos módulos simples al agregar funciones, tipos y módulos adicionales más complejos. Una versión simplificada sería:Módulos y campos de registro
module type SIMPLE = sig
type t
val to_string : t -> string
val of_string : string -> t
end
module Complex = functor (S:SIMPLE) -> struct
include S
let write db id t = db # write id (S.to_string t)
let read db id = db # read id |> BatOption.map S.of_string
end
No hay necesidad de dar al módulo sencilla un nombre, porque toda su funcionalidad está presente en el módulo extendido, y las funciones del módulo simples son generados por camlp4 basado en el tipo . El uso idiomático de estos funtores es:
module Int = Complex(struct
type t = int
end)
El problema aparece cuando estoy trabajando con registros:
module Point2D = Complex(struct
type t = { x : int ; y : int }
end)
let (Some location) = Point2D.read db "location"
Parece que hay una forma sencilla de acceder a los campos x
y y
definido anteriormente de fuera del módulo Point2D
, como location.x
o location.Point2D.x
. ¿Cómo puedo conseguir esto?
EDITAR: conforme a lo solicitado, aquí hay un ejemplo mínimo completa que muestra el problema:
module type TYPE = sig
type t
val default : t
end
module Make = functor(Arg : TYPE) -> struct
include Arg
let get = function None -> default | Some x -> (x : t)
end
module Made = Make(struct
type t = {a : int}
let default = { a = 0 } (* <-- Generated by camlp4 based on type t above *)
end)
let _ = (Made.get None).a (* <-- ERROR *)
Publicar código compilable sería de gran ayuda para obtener respuestas compilables. –