Sounds simple enough. I’ll take a look at it, thanks
Oh hm, maybe this is an even simpler path to solve your problem. Here’s a little experiment:
# module M1 = struct
type t = { a :int ; b : string }
end ;;
module M1 : sig type t = { a : int; b : string; } end
# module M2 = struct
type t = { a :int ; b : string ; c : float }
end ;;
module M2 : sig type t = { a : int; b : string; c : float; } end
# let migrate = fun {M1.a;b} -> let c = 4.0 in {M2.a;b;c};;
val migrate : M1.t -> M2.t = <fun>
So the function that maps a record of type M1.t
to a record of type M2.t
looks remarkably like the record-type itself with just the field-labels preserved. One could imagine a little PPX rewriter that did just that rewrite: rewrite a type to a pattern, and another one that did so to an expression, as in the manner of the function in the last expression above. Then combining these together, would get you your transformer, viz. migrate
above. One could imagine it as:
let migrate = fun [%recty: M1.t] -> let c = 4.0 in [%recty: M2.t] ;;
or maybe better (to reuse ppx_import to get the types copied-in)
let migrate = fun [%recty: [%import: M1.t]] -> let c = 4.0 in [%recty: [%import: M2.t]] ;;
These might be simple enough to implement easily with PPX rewriters.