(Introduced in OCaml 3.12, generalized in 4.06)
|
A “destructive” substitution (with ... := ...) behaves essentially like normal signature constraints (with ... = ...), but it additionally removes the redefined type or module from the signature.
Prior to OCaml 4.06, there were a number of restrictions: one could only remove types and modules at the outermost level (not inside submodules), and in the case of with type the definition had to be another type constructor with the same type parameters.
A natural application of destructive substitution is merging two signatures sharing a type name.
module type Printable = sig type t val print : Format.formatter -> t -> unit end module type Comparable = sig type t val compare : t -> t -> int end module type PrintableComparable = sig include Printable include Comparable with type t := t end
One can also use this to completely remove a field:
module type S = Comparable with type t := intmodule type S = sig val compare : int -> int -> int end
or to rename one:
module type S = sig type u include Comparable with type t := u endmodule type S = sig type u val compare : u -> u -> int end
Note that you can also remove manifest types, by substituting with the same type.
module type ComparableInt = Comparable with type t = int ;;module type ComparableInt = sig type t = int val compare : t -> t -> int end
module type CompareInt = ComparableInt with type t := intmodule type CompareInt = sig val compare : int -> int -> int end