# Sharing Constraints

Sometimes you actually want to expose the type in an implementation of a module. You might like to say "the module Ints implements Arith and the type t is int," and allow external users of the Ints module to use the fact that Ints.t is int.

OCaml lets you write sharing constraints that refine a signature by specifying equations that must hold on the abstract types in that signature. If T is a module type containing an abstract type t, then T with type t = int is a new module type that is the same as T, except that t is known to be int. For example, we could write:

module Ints : (Arith with type t = int) = struct
(* all of Ints as before *)
end


Now both Ints.(one + one) and Ints.(1 + 1) are legal.

We don't have to specify the sharing constraint in the original definition of the module. We can create a structure, bind it to a module name, then bind it to another module name with its types being either abstract or exposed:

module Ints = struct
type t    = int
let zero  = 0
let one   = 1
let (+)   = Stdlib.(+)
let ( * ) = Stdlib.( * )
let (~-)  = Stdlib.(~-)
end

module IntsAbstracted : Arith = Ints
(* IntsAbstracted.(1 + 1) is illegal *)

module IntsExposed : (Arith with type t = int) = Ints
(* IntsExposed.(1 + 1) is legal *)


This can be a useful technique for testing purposes: provide one name for a module that clients use in which the types are abstract, and provide another name that implementers use for testing in which the types are exposed.