From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id A7CE97F747 for ; Wed, 6 Aug 2014 14:14:04 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of trevorsummerssmith@gmail.com) identity=pra; client-ip=209.85.219.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="trevorsummerssmith@gmail.com"; x-sender="trevorsummerssmith@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of trevorsummerssmith@gmail.com designates 209.85.219.42 as permitted sender) identity=mailfrom; client-ip=209.85.219.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="trevorsummerssmith@gmail.com"; x-sender="trevorsummerssmith@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-oa0-f42.google.com) identity=helo; client-ip=209.85.219.42; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="trevorsummerssmith@gmail.com"; x-sender="postmaster@mail-oa0-f42.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ao4BADEb4lPRVdsqlGdsb2JhbABagkeBGFcEgnOuTZkCgV+IVQgWEAEBAQEHCwsJEiuEHBEEGQEbHgMSEDcCJAERAQUBPRMHiAsBAxGdCYMYaospgXKDEIpWChknDWaFfxEBBQ6IEIougVIFlSuGZ4FUjGiENxgphSEhLw X-IPAS-Result: Ao4BADEb4lPRVdsqlGdsb2JhbABagkeBGFcEgnOuTZkCgV+IVQgWEAEBAQEHCwsJEiuEHBEEGQEbHgMSEDcCJAERAQUBPRMHiAsBAxGdCYMYaospgXKDEIpWChknDWaFfxEBBQ6IEIougVIFlSuGZ4FUjGiENxgphSEhLw X-IronPort-AV: E=Sophos;i="5.01,811,1400018400"; d="scan'208";a="88468772" Received: from mail-oa0-f42.google.com ([209.85.219.42]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 06 Aug 2014 14:14:03 +0200 Received: by mail-oa0-f42.google.com with SMTP id n16so1742977oag.1 for ; Wed, 06 Aug 2014 05:14:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=mXEvOUpxEytirIUEfzwmM+ApriqwLXewERNBzo1EPDI=; b=uA2MHje/PIYLLVOHNbPlPx8vYo0WHcIn54vvTG6joI0yKa2mftK3j2KPev65/EkElC sJx4lELSKfMCzLKs04XT/NdbHU2gYLkgCPqxy0Zq/poCTP0XH60bUFKnyuEHuGZ6NIE2 oMnp9JoJ7/RM/aTTMVvbRUFLki5Q0gKH0w4wiuGCQ3RAIyJd+CSLSEGQbEzvWwdlMNKN dfZyr1HmXRUuN7hfPjn/M/rveSaSKlBZOmA34kDwt8w6YpwRDukjrZHB6wh0vKlvRV1c l5MM/xQr0SFs/Cv5aaMlPI1xwEk0E7d8UwlayzQ4Skmrfx2dcaFh+ScorCvc2aEAYLJO eSKA== MIME-Version: 1.0 X-Received: by 10.60.175.234 with SMTP id cd10mr14493992oec.80.1407327241840; Wed, 06 Aug 2014 05:14:01 -0700 (PDT) Received: by 10.182.128.100 with HTTP; Wed, 6 Aug 2014 05:14:01 -0700 (PDT) Date: Wed, 6 Aug 2014 08:14:01 -0400 Message-ID: From: Trevor Smith To: caml-list@inria.fr Content-Type: multipart/alternative; boundary=047d7bd6c6f6552c5204fff4e886 Subject: [Caml-list] Type Constraints and .mli --047d7bd6c6f6552c5204fff4e886 Content-Type: text/plain; charset=UTF-8 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 --047d7bd6c6f6552c5204fff4e886 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hello,

I have a question about using .mli files for increased readability. I= think my question boils down to: "Can one tersely add type constraint= s to a signature defined in a .mli in that same .mli file?"

Detailed problem:=C2=A0You want to have a read interface and a wr= ite interface for the same implementation.

<= div style=3D"font-family:arial,sans-serif;font-size:13px">We'll use a t= rivial example with a character and a name.

module type CharacterSig =3D sig
=C2=A0 val t
=C2=A0 val create : string -> t
=C2=A0 val name : t -> string
end

module type MutableCharacterSig =3D s= ig
<= div>=C2=A0 val t
=C2=A0 val create : string -> t
=C2=A0 val name : t -> string=
=C2=A0 val set_name : t -> stri= ng -> unit
end

module CharacterImpl =3D struct<= /font>
=C2=A0 type t =3D {n= ame : string ref}
= =C2=A0 let create name =C2=A0=3D
=C2=A0 =C2=A0 {name =3D ref name= }
=C2=A0 let name c= =3D !(c.name)
=C2=A0 let set_name c name =3D<= /font>
=C2=A0 =C2=A0=C2=A0c.name=C2=A0:=3D name
= end

module Character =3D (CharacterImpl : Chara= cterSig with type t =3D CharacterImpl.t)
module MutableC= haracter =3D (CharacterImpl : MutableCharacterSig with type t =3D Character= Impl.t)

But wh= at I would like is to specify the read and write signatures in .mli files f= or a more readable codebase.

So:

character.mli:
=C2=A0 val t
=C2=A0 val create : string -> t
=C2=A0 val name : t ->= ; string

mCharacter.mli:
=C2=A0 val t
= =C2=A0 val create : string -> t
=C2=A0 val name : t -> string
=C2=A0 val set_nam= e : t -> string -> unit

charac= terImpl.ml (* ... implementation as above ... *)

However, it is not clear to me that there is a way to attach the type const= raint to character.mli and mCharacter.mli, while keeping the terse readabil= ity of the .mli file. One idea for a solution, would be to reference a &quo= t;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 t= he .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:


module type CharacterS= ig =3D sig
=C2=A0 = =C2=A0 type t
=C2=A0= =C2=A0 val create : string -> t
=C2=A0 =C2=A0 val name : t ->= string
end

module T =3D (CharacterImpl : CharacterSig = with type t =3D CharacterImpl.t)
include T

However, it seems like the= re could be a slightly more readable way of doing this.

Thoughts? Thank you.

Trevor
--047d7bd6c6f6552c5204fff4e886--