From: Trevor Smith <trevorsummerssmith@gmail.com>
To: caml-list@inria.fr
Subject: [Caml-list] Type Constraints and .mli
Date: Wed, 6 Aug 2014 08:14:01 -0400 [thread overview]
Message-ID: <CAG-KTt_4CUmxmpoww-5aAR_4o5WH7hq_Dah1ENrHzA1ZHq4ogA@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 2214 bytes --]
Hello,
I have a question about using .mli files for increased readability. I think
my question boils down to: "Can one tersely add type constraints to a
signature defined in a .mli in that same .mli file?"
Detailed problem: You want to have a read interface and a write interface
for the same implementation.
We'll use a trivial example with a character and a name.
module type CharacterSig = sig
val t
val create : string -> t
val name : t -> string
end
module type MutableCharacterSig = sig
val t
val create : string -> t
val name : t -> string
val set_name : t -> string -> unit
end
module CharacterImpl = struct
type t = {name : string ref}
let create name =
{name = ref name }
let name c = !(c.name)
let set_name c name =
c.name := name
end
module Character = (CharacterImpl : CharacterSig with type t =
CharacterImpl.t)
module MutableCharacter = (CharacterImpl : MutableCharacterSig with type t
= CharacterImpl.t)
But what I would like is to specify the read and write signatures in .mli
files for a more readable codebase.
So:
character.mli:
val t
val create : string -> t
val name : t -> string
mCharacter.mli:
val t
val create : string -> t
val name : t -> string
val set_name : t -> string -> unit
characterImpl.ml (* ... implementation as above ... *)
However, it is not clear to me that there is a way to attach the type
constraint to character.mli and mCharacter.mli, while keeping the terse
readability of the .mli file. One idea for a solution, would be to
reference a "this" so that the interface could show that it was being
implemented by CharacterImpl, and include the type constraint.
The solution I've come to use, that is still pretty readable, is to define
the signature in the .ml file (so no .mli file) and then defining an
internal module which I include (so that I can still reference file name as
the module). So:
character.ml
module type CharacterSig = sig
type t
val create : string -> t
val name : t -> string
end
module T = (CharacterImpl : CharacterSig with type t = CharacterImpl.t)
include T
However, it seems like there could be a slightly more readable way of doing
this.
Thoughts? Thank you.
Trevor
[-- Attachment #2: Type: text/html, Size: 7599 bytes --]
next reply other threads:[~2014-08-06 12:14 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-06 12:14 Trevor Smith [this message]
2014-08-06 15:36 ` Török Edwin
2014-08-07 22:06 ` Trevor Smith
2014-08-08 8:19 ` Frédéric Bour
2014-08-06 22:06 ` Nick Lucaroni
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAG-KTt_4CUmxmpoww-5aAR_4o5WH7hq_Dah1ENrHzA1ZHq4ogA@mail.gmail.com \
--to=trevorsummerssmith@gmail.com \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox