From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id oBSGs6CH004365 for ; Tue, 28 Dec 2010 17:54:06 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AvQBAAOlGU2A1gkBe2dsb2JhbACWFo4vAQEWIgUfvzeFSgQ X-IronPort-AV: E=Sophos;i="4.60,239,1291590000"; d="scan'208";a="84811725" Received: from courier.cs.helsinki.fi (HELO mail.cs.helsinki.fi) ([128.214.9.1]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 28 Dec 2010 17:54:01 +0100 Received: from melkinpaasi.cs.helsinki.fi (melkinpaasi.cs.helsinki.fi [128.214.9.14]) (AUTH: PLAIN cs-relay, TLS: TLSv1/SSLv3,256bits,AES256-SHA) by mail.cs.helsinki.fi with esmtp; Tue, 28 Dec 2010 18:54:00 +0200 id 00093E45.4D1A1628.00002B53 Received: by melkinpaasi.cs.helsinki.fi (Postfix, from userid 37211) id 23B86821F3; Tue, 28 Dec 2010 18:54:00 +0200 (EET) Date: Tue, 28 Dec 2010 18:54:00 +0200 From: Lauri Alanko To: caml-list@inria.fr Message-ID: <20101228165359.GC12021@melkinpaasi.cs.helsinki.fi> References: <20101228140247.GB12021@melkinpaasi.cs.helsinki.fi> <4D19FB54.3000607@frisch.fr> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline In-Reply-To: <4D19FB54.3000607@frisch.fr> User-Agent: Mutt/1.5.20 (2009-06-14) Subject: Re: [Caml-list] Avoiding ml/mli code duplication On Tue, Dec 28, 2010 at 03:59:32PM +0100, Alain Frisch wrote: > (** BarDefs.ml **) > module type S = sig > type t > type u = A of t > end > > > (** Bar.mli **) > include BarDefs.S > val x: u list > > > (** Bar.ml **) > type t = X > module rec S_impl : BarDefs.S with type t := t = S_impl > include S_impl > let x = [A X] That's neat. You are using the recursive module trick that allows one to convert a value-less signature into a module: . Effectively, you replace my example's functor application with signature refining. (Incidentally, your code can simplified somewhat by moving the signature S into the body of BarDefs.mli and then using "module type of BarDefs" instead of "BarDefs.S".) However, the recursive module trick seems like quite a kludge. Perhaps there should be a "legitimized" way of producing a module with a certain value-less signature. For instance, instead of "module rec M : S = M" just allow "module M : S" within a module definition if S has no values? There's another approach to my original problem that unfortunately doesn't seem to work. In principle, we could have: (*** BarCore.mli ***) type t (*** BarCore.ml ***) type t = X (*** BarDefs.ml ***) include BarCore type u = A of t (*** Bar.mli ***) include module type of BarDefs val x : u list (*** Bar.ml ***) include BarDefs let x = [A X] Except, of course, that the constructor X is not visible in Bar.ml. I can't immediately see a way to make it visible in Bar.ml without also making it visible in Bar.mli. BarCore would need to have a separate "package-internal" signature that Bar.ml could use. Is there any way to achive this? Lauri