-mkSigmaTy tyvars theta tau = mkForAllTys tyvars (mkRhoTy theta tau)
-
-splitSigmaTy :: GenType flexi -> ([GenTyVar flexi], [(Class, [GenType flexi])], GenType flexi)
-splitSigmaTy ty =
- (tyvars, theta, tau)
- where
- (tyvars,rho) = splitForAllTys ty
- (theta,tau) = splitRhoTy rho
+splitRecNewType_maybe :: Type -> Maybe Type
+-- Newtypes are always represented by a NewTcApp
+-- Sometimes we want to look through a recursive newtype, and that's what happens here
+-- Only applied to types of kind *, hence the newtype is always saturated
+splitRecNewType_maybe (NoteTy _ ty) = splitRecNewType_maybe ty
+splitRecNewType_maybe (NewTcApp tc tys)
+ | isRecursiveTyCon tc
+ = ASSERT( tys `lengthIs` tyConArity tc && isNewTyCon tc )
+ -- The assert should hold because repType should
+ -- only be applied to *types* (of kind *)
+ Just (new_type_rep tc tys)
+splitRecNewType_maybe other = Nothing
+
+-----------------------------
+newTypeRep :: TyCon -> [Type] -> Type
+-- A local helper function (not exported)
+-- Expands a newtype application to
+-- *either* a vanilla TyConApp (recursive newtype, or non-saturated)
+-- *or* the newtype representation (otherwise)
+-- Either way, the result is not a NewTcApp
+--
+-- NB: the returned TyConApp is always deconstructed immediately by the
+-- caller... a TyConApp with a newtype type constructor never lives
+-- in an ordinary type
+newTypeRep tc tys
+ | not (isRecursiveTyCon tc), -- Not recursive and saturated
+ tys `lengthIs` tyConArity tc -- treat as equivalent to expansion
+ = new_type_rep tc tys
+ | otherwise
+ = TyConApp tc tys
+ -- ToDo: Consider caching this substitution in a NType
+
+----------------------------
+-- new_type_rep doesn't ask any questions:
+-- it just expands newtype, whether recursive or not
+new_type_rep new_tycon tys = ASSERT( tys `lengthIs` tyConArity new_tycon )
+ case newTyConRep new_tycon of
+ (tvs, rep_ty) -> substTyWith tvs tys rep_ty