I have a coordinate "class" (implemented using a factory function returning an object literal) in OCaml and am trying to figure out how to restrict the visibility of a method on that object to the module it was defined in.
Here's the source file
(* coordinate.ml *)
type coordinate = < get_x : int; get_y : int >
let create_coord ~x ~y = object
val x = x
val y = y
method get_x = x
method get_y = y
(* hide this method from public interface *)
method debug_print = Printf.printf "(x=%d, y=%d)\n"
end
and here's the interface
(* coordinate.mli *)
(* the type synonym coordinate is compatible with the "real"
* type, but does not expose the debug_print method *)
type coordinate = < get_x : int; get_y : int >
val create_coord : x:int -> y:int -> coordinate
My intent was to allow the object returned by create_coord to have all of methods visible inside the body of the Coordinate module. The only reason the coordinate type alias is repeated in the .ml file is to satisfy the compiler/allow it to be used in the .mli.
However, I want to prevent consumers of this module from using the debug_print method. I figured that, "since OCaml supports structural typing", an object type with strictly fewer methods would be a "compatible" type for the purposes of type ascription.
However, when I attempt to compile the files I get the following error:
$ ocamlc coordinate.mli
$ ocamlc coordinate.ml
File "coordinate.ml", line 1:
Error: The implementation coordinate.ml
does not match the interface coordinate.cmi:
Values do not match:
val create_coord :
x:'a ->
y:'b ->
< debug_print : int -> int -> unit; get_x : 'a; get_y : 'b >
is not included in
val create_coord : x:int -> y:int -> coordinate
File "coordinate.ml", line 3, characters 4-16: Actual declaration
Exit 2
Is there a way to limit the visibility of debug_print outside of Coordinate while making it freely accessible inside?