From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 6AF79BB84 for ; Tue, 10 Feb 2009 19:07:25 +0100 (CET) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ak8BAE9RkUlCbwQZk2dsb2JhbACUSQEBAQEJCQoJEQS/NIQaBg X-IronPort-AV: E=Sophos;i="4.38,187,1233529200"; d="scan'208";a="23871310" Received: from out1.smtp.messagingengine.com ([66.111.4.25]) by mail1-smtp-roc.national.inria.fr with ESMTP; 10 Feb 2009 19:07:24 +0100 Received: from compute2.internal (compute2.internal [10.202.2.42]) by out1.messagingengine.com (Postfix) with ESMTP id A6CCF29007A; Tue, 10 Feb 2009 13:07:23 -0500 (EST) Received: from heartbeat1.messagingengine.com ([10.202.2.160]) by compute2.internal (MEProxy); Tue, 10 Feb 2009 13:07:23 -0500 X-Sasl-enc: yJOs0dM0BkfURa2m1m53XQg363Paki/hXDOjwav0OVWL 1234289243 Received: from [192.168.1.10] (ALyon-157-1-32-198.w86-193.abo.wanadoo.fr [86.193.247.198]) by mail.messagingengine.com (Postfix) with ESMTPSA id 90F8A31557; Tue, 10 Feb 2009 13:07:22 -0500 (EST) Message-ID: <4991C1DF.8010503@ens-lyon.org> Date: Tue, 10 Feb 2009 19:05:19 +0100 From: Martin Jambon User-Agent: Thunderbird 2.0.0.17 (X11/20081008) MIME-Version: 1.0 To: David Rajchenbach-Teller Cc: OCaml Subject: Re: [Caml-list] Hiding private types References: <1234286066.6457.35.camel@Blefuscu> In-Reply-To: <1234286066.6457.35.camel@Blefuscu> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; ens-lyon:01 leaking:01 dependencies:01 toplevel:01 toplevel:01 sig:01 sig:01 val:01 val:01 struct:01 wrote:01 defines:01 caml-list:01 int:01 int:01 David Rajchenbach-Teller wrote: > Dear list, > > I'm looking for a way to remove one or two annoyances of Batteries, > which are related to private magic leaking into the type system and into > the documentation. > > > > We define a module [IO] with, among other things, a type [output]. In > fact, in order to avoid circular dependencies, [output] is actually > defined in a private module [InnerIO], which lets other modules such as > [ExtString] use [output] and still be used by [IO]. For instance, > [ExtString] defines a function [print : InnerIO.output -> string -> > unit]. > > At a later stage, we pack [IO], [InnerIO], [ExtString] and others into a > module [Extlib] and we later define a module [Batteries] containing > > module IO = Extlib.IO > module String = ExtString.String > > etc. > > > Now, all of this works. Unfortunately, the types visible by the user, > either from the toplevel, from error messages or from -dannot, reveal > too much from the inner workings of Batteries. > > For instance, [InnerIO], as implied by the name, is private. The > existence of this module should not be visible by the user. > Unfortunately, on the toplevel, we have > > # String.print;; > - : Extlib.InnerIO.output -> string -> unit = > > Two abstractions have leaked out: > * the existence of [InnerIO] > * the existence of [Extlib] > > I would rather have > > # String.print;; > - : IO.output -> string -> unit = > > or, at worst > > # String.print;; > - : Batteries.IO.output -> string -> unit = > > > Does anyone have an idea of how we could/should do this? It looks like you can applying a signature to Batteries.IO does the trick: (* IO's signature *) module type A_sig = sig type t val add : t -> t -> t val create : unit -> t end (* Extlib.IO *) module A : A_sig = struct type t = int let add = ( + ) let create () = 1 end (* Batteries.IO, version 1 *) module B = A (* Batteries.IO, version 2 *) module C : A_sig = A This is the problem that you're having, i.e. A.t appears in the error message: # B.create () = 1;; Characters 14-15: B.create () = 1;; ^ This expression has type int but is here used with type B.t = A.t This looks better: # C.create () = A.create ();; Characters 14-25: C.create () = A.create ();; ^^^^^^^^^^^ This expression has type A.t but is here used with type C.t I just hope it works for your problem. Martin -- http://mjambon.com/