mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
mk_tuple boxity arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con
                               tup_sort
                               prom_tc flavour

        flavour = case boxity of
                    Boxed   -> VanillaAlgTyCon (mkPrelTyConRepName tc_name)
                    Unboxed -> UnboxedAlgTyCon

        tup_sort = case boxity of
                      Boxed   -> BoxedTuple
                      Unboxed -> UnboxedTuple

        prom_tc = case boxity of
                    Boxed   -> Promoted (mkPromotedTyCon tycon (promoteKind tc_kind))
                    Unboxed -> NotPromoted

        modu = case boxity of
                    Boxed -> gHC_TUPLE
                    Unboxed -> gHC_PRIM

        tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind

        res_kind = case boxity of
                     Boxed   -> liftedTypeKind
                     Unboxed -> unliftedTypeKind

        tyvars = take arity $ case boxity of
                   Boxed   -> alphaTyVars
                   Unboxed -> openAlphaTyVars

        tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
        tyvar_tys = mkTyVarTys tyvars
        dc_name   = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
                                  (AConLike (RealDataCon tuple_con)) BuiltInSyntax
        tc_uniq   = mkTupleTyConUnique   boxity arity
        dc_uniq   = mkTupleDataConUnique boxity arity
mk_tuple :: Boxity -> Int -> (TyCon,DataCon)
mk_tuple boxity arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con
                               tup_sort
                               prom_tc flavour

        flavour = case boxity of
                    Boxed   -> VanillaAlgTyCon (mkPrelTyConRepName tc_name)
                    Unboxed -> UnboxedAlgTyCon

        tup_sort = case boxity of
                      Boxed   -> BoxedTuple
                      Unboxed -> UnboxedTuple

        prom_tc = case boxity of
                    Boxed   -> Promoted (mkPromotedTyCon tycon (promoteKind tc_kind))
                    Unboxed -> NotPromoted

        modu = case boxity of
                    Boxed -> gHC_TUPLE
                    Unboxed -> gHC_PRIM

        tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind

        res_kind = case boxity of
                     Boxed   -> liftedTypeKind
                     Unboxed -> unliftedTypeKind

        tyvars = take arity $ case boxity of
                   Boxed   -> alphaTyVars
                   Unboxed -> openAlphaTyVars

        tuple_con = pcDataCon dc_name tyvars tyvar_tys tycon
        tyvar_tys = mkTyVarTys tyvars
        dc_name   = mkWiredInName modu (mkTupleOcc dataName boxity arity) dc_uniq
                                  (AConLike (RealDataCon tuple_con)) BuiltInSyntax
        tc_uniq   = mkTupleTyConUnique   boxity arity
        dc_uniq   = mkTupleDataConUnique boxity arity
mk_tuple boxity arity = (tycon, tuple_con)
  where
        tycon   = mkTupleTyCon tc_name tc_kind arity tyvars tuple_con
                               tup_sort
                               prom_tc flavour

        flavour = case boxity of
                    Boxed   -> VanillaAlgTyCon (mkPrelTyConRepName tc_name)
                    Unboxed -> UnboxedAlgTyCon

        tup_sort = case boxity of
                      Boxed   -> BoxedTuple
                      Unboxed -> UnboxedTuple

        prom_tc = case boxity of
                    Boxed   -> Promoted (mkPromotedTyCon tycon (promoteKind tc_kind))
                    Unboxed -> NotPromoted

        modu = case boxity of
                    Boxed -> gHC_TUPLE
                    Unboxed -> gHC_PRIM

        tc_name = mkWiredInName modu (mkTupleOcc tcName boxity arity) tc_uniq
                                (ATyCon tycon) BuiltInSyntax
        tc_kind = mkArrowKinds (map tyVarKind tyvars) res_kind

        res_kind = case boxity of
                     Boxed   -> liftedTypeKind
                     Unboxed -> unliftedTypeKind

        tyvars = take arity $ case boxity of
                   Boxed   -> alphaTyVars
                   Unboxed -> openAlphaTyVars

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