On Tue, May 4, 2010 at 9:37 AM, Edgar Friendly <thelema314@gmail.com> 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