+ co_con_arity = length tvs
+
+ rule args = (TyConApp tycon tys, substTyWith tvs tys rhs_ty, rest)
+ where
+ tys = take co_con_arity args
+ rest = drop co_con_arity args
+
+-- Coercion identifying a data/newtype representation type and its family
+-- instance. It has the form `Co tvs :: F ts :=: R tvs', where `Co' is the
+-- coercion tycon built here, `F' the family tycon and `R' the (derived)
+-- representation tycon.
+--
+mkDataInstCoercion :: Name -- unique name for the coercion tycon
+ -> [TyVar] -- type parameters of the coercion (`tvs')
+ -> TyCon -- family tycon (`F')
+ -> [Type] -- type instance (`ts')
+ -> TyCon -- representation tycon (`R')
+ -> TyCon -- => coercion tycon (`Co')
+mkDataInstCoercion name tvs family instTys rep_tycon
+ = mkCoercionTyCon name coArity (mkKindingFun rule)
+ where
+ coArity = length tvs
+
+ rule args = (substTyWith tvs tys $ -- with sigma = [tys/tvs],
+ TyConApp family instTys, -- sigma (F ts)
+ TyConApp rep_tycon tys, -- :=: R tys
+ rest) -- surplus arguments
+ where
+ tys = take coArity args
+ rest = drop coArity args