Estoy tratando de entender una cosa específica acerca de los módulos OCaml y su compilación:declaración de tipo de OCaml (ml/MLI)
estoy yo obligado a redeclare tipos ya declarados en un .mli
dentro de las implementaciones específicas .ml
?
Sólo para dar un ejemplo:
(* foo.mli *)
type foobar = Bool of bool | Float of float | Int of int
(* foo.ml *)
type baz = foobar option
Esto, según mi forma habitual de pensar en interfaces/implementaciones, debe estar bien, pero se dice
Error: Unbound type constructor foobar
al tratar de compilar con
ocamlc -c foo.mli
ocamlc -c foo.ml
Por supuesto, el error desaparece si declaro foobar
dentro de foo.ml
también, pero parece una forma compleja ya que tengo que sincronizar todo en cada cambio.
¿Hay alguna manera de evitar esta redundancia o me veo obligado a redeclarar los tipos cada vez?
Gracias de antemano
No creo que haya ninguna limitación al permitir que un archivo '.ml' infiera los tipos descritos en el' .mli' acoplado. Por lo que entiendo, la implementación real __forces redundancy__, pero también que __ las dos firmas deben ser iguales__ por lo que esto está doblando las mismas declaraciones. Es por eso que pensé que debería ser consciente de estas declaraciones sin tener que copiarlas y pegarlas. El algoritmo de inferencia de tipo no sufriría problemas según yo. – Jack
No obliga a la redundancia ni requiere que las firmas sean idénticas, solo que la declaración en el archivo ml debe ser igual o más específica que la declaración mli. El objetivo del mli es definir qué es visible en la interfaz, por lo que puede elegir no exponer el tipo (en cuyo caso no está en el archivo mli) o puede elegir exponer que hay un tipo, pero no cómo se usa (en cuyo caso las declaraciones de tipo son diferentes). Por supuesto, en su situación, tendría sentido para el compilador asumir el tipo ya que está completamente definido en el mli. –
@Niki no hay redundancia forzada en declaraciones * value * (que son opcionales en el .ml de todos modos), y en la práctica es donde entra "al menos tan específico como". Pero en el 99% de los casos aparece un * manifest type * en una interfaz es idéntica a la definición del tipo en la implementación. Esto es redundante e irritante, pero como diseñador de lenguaje he pensado mucho sobre este problema y no he presentado una propuesta que creo que sea tanto de principios como significativamente mejor que OCaml. –