Several of my modules contain global class instances that implement a given class type with two methods, private_method
and public_method
.
I want MyModule.my_instance # public_method
to be available from anywhere in my program, and MyModule.my_instance # private_method
to be available only within MyModule
.
I have attempted the following:
class type public_type = object
method public_method : int
end ;;
class type private_type = object
method public_method : int
method private_method : int
end ;;
let make_private : unit -> private_type = fun () -> object
method public_method = 0
method private_method = 0
end ;;
module type MY_MODULE = sig
val my_instance : public_type
end
module MyModule : MY_MODULE = struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end
However, this results in an error:
Values do not match:
val my_instance : private_type
is not included in
val my_instance : public_type
I could write the coercion manually:
module MyModule : MY_MODULE = struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
let my_instance = (my_instance :> public_type)
end
But I'd rather not double the code size for something as simple as this.
Do you have any suggestions on why this happens, and how I can work around it?
There are no implicit coercions in ocaml. Maybe it is worth putting coercion into functor (if you have several modules with these same properties) :
module Hide(M:sig val my_instance : private_type end) : MY_MODULE =
struct
let my_instance = (M.my_instance :> public_type)
end
module MyModule = Hide (struct
let my_instance = make_private ()
let _ = print_int (my_instance # private_method)
end)