在 OCaml 4.06 之前,存在一些限制:只能在最外層(而非子模組內)移除型別和模組,且在 with type 的情況下,定義必須是另一個具有相同型別參數的型別建構子。
破壞性替換的一個自然應用是合併兩個共享型別名稱的簽章。
moduletype Printable = sigtype t val print : Format.formatter -> t -> unit endmoduletype Comparable = sigtype t val compare : t -> t -> int endmoduletype PrintableComparable = siginclude Printable include Comparable withtype t := t end
也可以使用它來完全移除一個欄位
moduletype S = Comparable withtype t := int
moduletype S = sigval compare : int -> int -> int end
或重新命名一個
moduletype S = sigtype u include Comparable withtype t := u end
moduletype S = sigtype u val compare : u -> u -> int end
請注意,您也可以移除顯式型別,透過使用相同的型別進行替換。
moduletype ComparableInt = Comparable withtype t = int ;;
moduletype ComparableInt = sigtype t = int val compare : t -> t -> int end
moduletype CompareInt = ComparableInt withtype t := int
moduletype CompareInt = sigval compare : int -> int -> int end
moduletype S = sigtype t module Sub : sigtype outer := t type t val to_outer : t -> outer endend
moduletype S = sigtype t module Sub : sigtype t val to_outer : t -> t/2 endend
請注意,與型別宣告不同,型別替換宣告不是遞迴的,因此會拒絕如下替換
#moduletype S = sigtype 'a poly_list := [ `Cons of 'a * 'a poly_list | `Nil ] end ;;
Error: Unbound type constructor poly_list
局部替換也可以用於為函子應用所引入的型別或模組型別提供局部名稱
#moduletype F = sigtype set := Set.Make(Int).t moduletype Type = sigtype t endmodule Nest : Type -> sigmoduletype T = Type endmoduletype T := Nest(Int).T val set: set val m : (module T) end;;
moduletype F = sigmoduletype Type = sigtype t endmodule Nest : Type -> sigmoduletype T = Type endval set : Set.Make(Int).t val m : (module Nest(Int).T) end
#moduletype ENDO = sigmoduletype T module F: T -> T endmodule Endo(X: sigmoduletype T end): ENDO withmoduletype T = X.T = structmoduletype T = X.T module F(X:T) = X end;;
moduletype ENDO = sigmoduletype T module F : T -> T endmodule Endo : functor (X : sigmoduletype T end) -> sigmoduletype T = X.T module F : T -> T end
也可以用等效的模組型別替換具體的模組型別。
moduletype A = sigtype x moduletype R = sigtype a = A of x type b endendmoduletype S = sigtype a = A of int type b endmoduletype B = A withtype x = int andmoduletype R = S
然而,這種替換從來都不是必要的。
破壞性模組類型替換會從簽名中移除模組類型替換
#moduletype ENDO' = ENDO withmoduletype T := ENDO;;