On Tue, May 4, 2010 at 9:37 AM, Edgar Friendly wrote: > module M : sig > type momentum > val of_kin : kinematic -> momentum > val to_kin : momentum -> kinematic > end = struct > type momentum = kinematic > let of_kin x = x > let to_kin x = x > end > > Yes, it's a lot of boilerplate for each type, but you only have to write it > once (per type), and cross-module inlining should give zero runtime cost. > If not, use "%identity", and expose it in the interface. This method is > along the lines of Anthony's proposal #4. You can do the above solution with essentially no boilerplate: module M = struct type t = kinematic val to_kin x = x val of_kin x = x end module type S = sig type t val to_kin : t -> kinematic val of_kin : kinematic -> t end module Momentum : S = M module Position : S = M module Force : S = M and so on. Just one line per kinematic-like type you want to create. That said, I still think the phantom type solution will end up cleaner. y