mk_tuple :: TupleSort -> Int -> (TyCon,DataCon)
mk_tuple sort arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con sort prom_tc
        prom_tc = case sort of
          BoxedTuple      -> Just (mkPromotedTyCon tycon (promoteKind tc_kind))
          UnboxedTuple    -> Nothing
          ConstraintTuple -> Nothing

        modu    = mkTupleModule sort
        tc_name = mkWiredInName modu (mkTupleOcc tcName sort arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
        res_kind = case sort of
          BoxedTuple      -> liftedTypeKind
          UnboxedTuple    -> unliftedTypeKind
          ConstraintTuple -> constraintKind

        tyvars = take arity $ case sort of
          BoxedTuple      -> alphaTyVars
          UnboxedTuple    -> openAlphaTyVars
          ConstraintTuple -> tyVarList constraintKind

        tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
        tyvar_tys = mkTyVarTys tyvars
        dc_name   = mkWiredInName modu (mkTupleOcc dataName sort arity) dc_uniq
                                  (AConLike (RealDataCon tuple_con)) BuiltInSyntax
        tc_uniq   = mkTupleTyConUnique   sort arity
        dc_uniq   = mkTupleDataConUnique sort arity
mk_tuple :: TupleSort -> Int -> (TyCon,DataCon)
mk_tuple sort arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con sort prom_tc
        prom_tc = case sort of
          BoxedTuple      -> Just (mkPromotedTyCon tycon (promoteKind tc_kind))
          UnboxedTuple    -> Nothing
          ConstraintTuple -> Nothing

        modu    = mkTupleModule sort
        tc_name = mkWiredInName modu (mkTupleOcc tcName sort arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
        res_kind = case sort of
          BoxedTuple      -> liftedTypeKind
          UnboxedTuple    -> unliftedTypeKind
          ConstraintTuple -> constraintKind

        tyvars = take arity $ case sort of
          BoxedTuple      -> alphaTyVars
          UnboxedTuple    -> openAlphaTyVars
          ConstraintTuple -> tyVarList constraintKind

        tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
        tyvar_tys = mkTyVarTys tyvars
        dc_name   = mkWiredInName modu (mkTupleOcc dataName sort arity) dc_uniq
                                  (AConLike (RealDataCon tuple_con)) BuiltInSyntax
        tc_uniq   = mkTupleTyConUnique   sort arity
        dc_uniq   = mkTupleDataConUnique sort arity
mk_tuple sort arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con sort prom_tc
        prom_tc = case sort of
          BoxedTuple      -> Just (mkPromotedTyCon tycon (promoteKind tc_kind))
          UnboxedTuple    -> Nothing
          ConstraintTuple -> Nothing

        modu    = mkTupleModule sort
        tc_name = mkWiredInName modu (mkTupleOcc tcName sort arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind
        res_kind = case sort of
          BoxedTuple      -> liftedTypeKind
          UnboxedTuple    -> unliftedTypeKind
          ConstraintTuple -> constraintKind

        tyvars = take arity $ case sort of
          BoxedTuple      -> alphaTyVars
          UnboxedTuple    -> openAlphaTyVars
          ConstraintTuple -> tyVarList constraintKind

        tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
        tyvar_tys = mkTyVarTys tyvars
        dc_name   = mkWiredInName modu (mkTupleOcc dataName sort arity) dc_uniq
                                  (AConLike (RealDataCon tuple_con)) BuiltInSyntax
        tc_uniq   = mkTupleTyConUnique   sort arity
        dc_uniq   = mkTupleDataConUnique sort arity