Hi Jun,

You can achieve this by implying an extra layer of indirection, i.e., by having two levels of interfaces. For example, 

   * A.ml - implementation of module A
   * A.mli - private interface of module A
   * B.ml  - implementation of module B that may rely on anything in A.mli
   * Std.ml - a set of modules that you would like to import, e.g., `module A = A`, `module B = B` 
   * Std.mli - public interface specification


Next, you deploy `std.cmxa` and `std.cmi` but keep `a.cmi` and `b.cmi` to yourself. This will prevent users from accessing your private modules A and B directly. (In oasis you can use PrivateModules stanza for this)

Now you will have `Std.A` and `Std.B` that exposes as much as you want. Not sure whether it will work with the `-pack`, but you can use this approach instead of it. This is how we address the same issue in [BAP][1]

Cheers,
Ivan

[1]: https://github.com/BinaryAnalysisPlatform/bap
   

On Thu, Apr 26, 2018 at 10:18 AM, Jun Inoue <jun.lambda@gmail.com> wrote:
Dear list,

Is there a way to make a type concrete inside a library, yet opaque to
library users, preferably in a way that works with -pack?  This is a
nagging issue in our sundials package
(http://inria-parkas.github.io/sundialsml/).

Basically, we have a type declared in one module of the library that
is pattern-matched upon in other modules, like:

(* private.ml *)
type opaque_type = Foo | Bar

(* public.ml *)
let f : opaque_type -> int = function
  | Foo -> 0
  | Bar -> 1

There are a few constraints:
- We don't want users to be able to pattern-match on opaque_type.
- We need multiple modules in the library to pattern-match on
opaque-type (so moving opaque_typ e to public.ml is not an option).
- To avoid namespace pollution, we want to pack the whole library
(with ocamlc -pack) as a single Sundials module, so the user sees a
Sundials.Public module instead of just Public.

Is this possible?  Right now, we just collect public.cmo and
private.cmo into sundials.cma and throw away private.cmi.  But this
doesn't work with packing:

$ ocamlc -pack -o sundials.cmo private.cmo public.cmo

demands that there be a private.cmi.

--
Jun Inoue

--
Caml-list mailing list.  Subscription management and archives:
https://sympa.inria.fr/sympa/arc/caml-list
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
Bug reports: http://caml.inria.fr/bin/caml-bugs