azimut has quit [Remote host closed the connection]
azimut has joined #ocaml
<discocaml>
<MasterBuilder> can somebody explain why http://dev.realworldocaml.org/files-modules-and-programs.html#nested-modules here `Username.t` and `Hostname.t` are distinct types? I suppose it has something to do with the fact that `t` is not concrete in the signature, but I still don't understand why they are distinct
<discocaml>
<ilo Kali> `Username.t` and `Hostname.t` are both abstract types, so even if their concrete type is the same, they are not the same type *outside* of the module
<discocaml>
<ilo Kali> this allows the user of these modules to never have to worry about the underlying implementation of that type—even if it changes drastically internally, it's still the same type to them externally
chrisz has quit [Ping timeout: 268 seconds]
chrisz has joined #ocaml
<discocaml>
<ilo Kali> Consider this snippet given in the section:
<discocaml>
<ilo Kali> ```ocaml
<discocaml>
<ilo Kali> module type ID = sig
<discocaml>
<ilo Kali> type t
<discocaml>
<ilo Kali> val of_string : string -> t
<discocaml>
<ilo Kali> val to_string : t -> string
<discocaml>
<ilo Kali> val ( = ) : t -> t -> bool
<discocaml>
<ilo Kali> end
<discocaml>
<ilo Kali> ```
<discocaml>
<ilo Kali> This implies that for all modules that satisfy this signature, there exists a type `t` in them that satisfies those functions' type signatures: it doesn't matter what the actual type `t` is, as long as the signature holds.
<discocaml>
<ilo Kali> because `t` could be any type, it must be abstract
<discocaml>
<ilo Kali> and abstract types are not equivalent, even if the internal type is
<discocaml>
<MasterBuilder> Okay, cool, got it, I was a bit tripped up by the comparison failing, although I was aware the type was not visible outside the module
<discocaml>
<MasterBuilder> thanks 🙂
<discocaml>
<ilo Kali> however, you can actually "enrich" the module's signatures to make the underlying type accessible to the outside world, if you wanted to
<discocaml>
<MasterBuilder> to continue with the string example, is it possible to create a new module with the module type of `String` but with the type of `t` abstract?
<discocaml>
<MasterBuilder> could I bother you to show what that looks like?
<discocaml>
<ilo Kali> <continuation of my message, for irc users> if you change the following lines
<discocaml>
<ilo Kali> ```ocaml
<discocaml>
<ilo Kali> module Username : ID = String_id
<discocaml>
<ilo Kali> module Hostname : ID = String_id
<discocaml>
<ilo Kali> ```
<discocaml>
<ilo Kali> to
<discocaml>
<ilo Kali> ```ocaml
<discocaml>
<ilo Kali> module Username : (ID with type t = string) = String_id (* parentheses unnecessary but added for clarity *)
<discocaml>
<ilo Kali> module Hostname : (ID with type t = string) = String_id
<discocaml>
<ilo Kali> ```
<discocaml>
<ilo Kali> they do become comparable
<discocaml>
<MasterBuilder> I see
<discocaml>
<ilo Kali> if there are multiple abstract types you wish to expose, you can use `and type ... = ...` to specify those ones, too
<discocaml>
<MasterBuilder> got it
<discocaml>
<MasterBuilder> and can you do the opposite? Like (pseudocode) `... with type t ...`
<discocaml>
<MasterBuilder> making it abstract
<discocaml>
<ilo Kali> hm, i am not sure. someone else will have to answer that