-isAlgTyCon (DataTyCon _ _ _ _ _ _ _ _) = True
-isAlgTyCon (TupleTyCon _ _ _) = True
-isAlgTyCon other = False
-
--- isDataTyCon returns False for @newtype@.
-isDataTyCon (DataTyCon _ _ _ _ _ _ _ DataType) = True
-isDataTyCon (TupleTyCon _ _ _) = True
-isDataTyCon other = False
-
-maybeNewTyCon :: TyCon -> Maybe ([TyVar], Type) -- Returns representation type info
-maybeNewTyCon (DataTyCon _ _ _ _ _ (con:null_cons) _ NewType)
- = ASSERT( null null_cons && null null_tys)
- Just (tyvars, rep_ty)
- where
- (tyvars, theta, tau) = splitSigmaTy (idType con)
- (rep_ty:null_tys, res_ty) = splitFunTy tau
-
-maybeNewTyCon other = Nothing
-
-isNewTyCon (DataTyCon _ _ _ _ _ _ _ NewType) = True
-isNewTyCon other = False
-
-isSynTyCon (SynTyCon _ _ _ _ _ _) = True
-isSynTyCon _ = False
-
-isEnumerationTyCon (TupleTyCon _ _ arity)
- = arity == 0
-isEnumerationTyCon (DataTyCon _ _ _ _ _ data_cons _ _)
- = not (null data_cons) && all isNullaryDataCon data_cons
-
-isTupleTyCon (TupleTyCon _ _ arity) = arity >= 2 -- treat "0-tuple" specially
-isTupleTyCon (SpecTyCon tc tys) = isTupleTyCon tc
-isTupleTyCon other = False
-\end{code}
-
-\begin{code}
--- Special cases to avoid reconstructing lots of kinds
-kind1 = mkBoxedTypeKind `mkArrowKind` mkBoxedTypeKind
-kind2 = mkBoxedTypeKind `mkArrowKind` kind1
-
-tyConKind :: TyCon -> Kind
-tyConKind FunTyCon = kind2
-tyConKind (DataTyCon _ _ kind _ _ _ _ _) = kind
-tyConKind (PrimTyCon _ _ kind _ _) = kind
-tyConKind (SynTyCon _ _ k _ _ _) = k
-
-tyConKind (TupleTyCon _ _ n)
- = mkArrow n
- where
- mkArrow 0 = mkBoxedTypeKind
- mkArrow 1 = kind1
- mkArrow 2 = kind2
- mkArrow n = mkBoxedTypeKind `mkArrowKind` mkArrow (n-1)
-
-tyConKind (SpecTyCon tc tys)
- = spec (tyConKind tc) tys
- where
- spec kind [] = kind
- spec kind (Just _ : tys) = spec (resultKind kind) tys
- spec kind (Nothing : tys) =
- argKind kind `mkArrowKind` spec (resultKind kind) tys
+isAlgTyCon :: TyCon -> Bool
+isAlgTyCon (AlgTyCon {}) = True
+isAlgTyCon (TupleTyCon {}) = True
+isAlgTyCon other = False
+
+algTyConRhs :: TyCon -> AlgTyConRhs
+algTyConRhs (AlgTyCon {algRhs = rhs}) = rhs
+algTyConRhs (TupleTyCon {dataCon = dc}) = DataTyCon [dc] False
+
+isDataTyCon :: TyCon -> Bool
+-- isDataTyCon returns True for data types that are represented by
+-- heap-allocated constructors.
+-- These are srcutinised by Core-level @case@ expressions, and they
+-- get info tables allocated for them.
+-- True for all @data@ types
+-- False for newtypes
+-- unboxed tuples
+isDataTyCon (AlgTyCon {algRhs = rhs})
+ = case rhs of
+ DataTyCon _ _ -> True
+ NewTyCon _ _ _ -> False
+ AbstractTyCon -> panic "isDataTyCon"
+
+isDataTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
+isDataTyCon other = False
+
+isNewTyCon :: TyCon -> Bool
+isNewTyCon (AlgTyCon {algRhs = NewTyCon _ _ _}) = True
+isNewTyCon other = False
+
+isProductTyCon :: TyCon -> Bool
+-- A "product" tycon
+-- has *one* constructor,
+-- is *not* existential
+-- but
+-- may be DataType or NewType,
+-- may be unboxed or not,
+-- may be recursive or not
+isProductTyCon tc@(AlgTyCon {}) = case algRhs tc of
+ DataTyCon [data_con] _ -> not (isExistentialDataCon data_con)
+ NewTyCon _ _ _ -> True
+ other -> False
+isProductTyCon (TupleTyCon {}) = True
+isProductTyCon other = False
+
+isSynTyCon :: TyCon -> Bool
+isSynTyCon (SynTyCon {}) = True
+isSynTyCon _ = False
+
+isEnumerationTyCon :: TyCon -> Bool
+isEnumerationTyCon (AlgTyCon {algRhs = DataTyCon _ is_enum}) = is_enum
+isEnumerationTyCon other = False
+
+isTupleTyCon :: TyCon -> Bool
+-- The unit tycon didn't used to be classed as a tuple tycon
+-- but I thought that was silly so I've undone it
+-- If it can't be for some reason, it should be a AlgTyCon
+isTupleTyCon (TupleTyCon {}) = True
+isTupleTyCon other = False
+
+isUnboxedTupleTyCon :: TyCon -> Bool
+isUnboxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = not (isBoxed boxity)
+isUnboxedTupleTyCon other = False
+
+isBoxedTupleTyCon :: TyCon -> Bool
+isBoxedTupleTyCon (TupleTyCon {tyConBoxed = boxity}) = isBoxed boxity
+isBoxedTupleTyCon other = False
+
+tupleTyConBoxity tc = tyConBoxed tc
+
+isRecursiveTyCon :: TyCon -> Bool
+isRecursiveTyCon (AlgTyCon {algTyConRec = Recursive}) = True
+isRecursiveTyCon other = False
+
+isHiBootTyCon :: TyCon -> Bool
+-- Used for knot-tying in hi-boot files
+isHiBootTyCon (AlgTyCon {algRhs = AbstractTyCon}) = True
+isHiBootTyCon other = False
+
+isForeignTyCon :: TyCon -> Bool
+-- isForeignTyCon identifies foreign-imported type constructors
+-- For the moment, they are primitive but lifted, but that may change
+isForeignTyCon (PrimTyCon {isUnLifted = is_unlifted}) = not is_unlifted
+isForeignTyCon other = False