I confused with module type in Ocaml.
I wondered that in which situation we should use module type?
I usually use module sig in .mli to expose some detail, and put corresponding implementation module struct in .ml.
For example:
.mli
module A:
sig
type t = T of string
end
.ml
module A =
struct
type t = T of string
end
For this reason, I think Ocaml's module like .h and .c file in C.
I know that module type can declare a interface, but the interface were not as same as Java's interface.
Like an example in book:
open Core.Std
module type ID = sig
type t
val of_string : string -> t
val to_string : t -> string
end
module String_id = struct
type t = string
let of_string x = x
let to_string x = x
end
module Username : ID = String_id
module Hostname : ID = String_id
type session_info = { user: Username.t;
host: Hostname.t;
when_started: Time.t;
}
let sessions_have_same_user s1 s2 =
s1.user = s2.host
The preceding code has a bug: it compares the username in one session to the host in the other session, when it should be comparing the usernames in both cases.
It seems that module type can not provide a new common super type for it's implementation.
What the real application for module type??
Here, the module type is used to hide the type t
to the user of the module.
When one makes use of Username.t
or Hostname.t
one can not rely on those types being strings, integers, or any specific type. The module type makes them opaque, as if they were not part of the interface of the module, but only an implementation detail, that the module writer is going to change in the future.
Basically, the user of the module can only act on type t
through the module functions.
The compiler checks that the user code does not make any assumptions about what these types t
actually are, so that in the future the module writer can change them without breaking the user code.
As it already mentioned, here module type is used to achieve more abstract vision of type t
. When you define Username
and Hostname
as two separate modules its means that logically they must be different and that signature of this modules it's the only possible way to work with them.
But you're wrong when you say:
It seems that module type can not provide a new common super type for it's implementation.
Actually you can precise that Username.t
and Hostname.t
are the same types.
module Username = (String_id : ID with type t = String_id.t)
module Hostname = (String_id : ID with type t = String_id.t)
Username.to_string (Hostname.of_string "hi")
Here it's useless but sometimes it's really helpful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With