For upgrading DAR versions, I copy contracts created using the old version into contracts created using the new version. For the situation that the fields of the contracts didn’t change, I can do this without enumerating all the fields. For example, for a template C that exists unchanged in both versions 1 and 2, this works:
upgrade : C1 -> Update C2
upgrade c1@(C1 with ..) = do
let _ = c1
c2cid <- create C2 with
..
fetch c2cid
Unfortunately, you cannot do that polymorphically. Record wildcards (that’s what the .. match is called) always have to match on a specific record.
What you could do is introduce a new typeclass that defines the conversion, implement that for all types you care about (for that you can use record wildcards) and then use that to do generic operations:
class Convertible a b where
convert : a -> b
instance Convertible C1 C2 where
convert (C1 with ..) = C2 with ..
instance (Template c0, Template c1, Convertible c0 c1) => Upgrader c0 c1 where
upgrade c0 = do
a2cid <- create @C1 (convert c0)
fetch a2cid