-sourceTypeRep :: SourceType -> Type
--- Convert a predicate to its "representation type";
--- the type of evidence for that predicate, which is actually passed at runtime
-sourceTypeRep (IParam n ty) = ty
-sourceTypeRep (ClassP clas tys) = mkTyConApp (classTyCon clas) tys
- -- Note the mkTyConApp; the classTyCon might be a newtype!
-sourceTypeRep (NType tc tys) = case newTyConRep tc of
- (tvs, rep_ty) -> substTy (mkTyVarSubst tvs tys) rep_ty
+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
+-- It only strips *one layer* off, so the caller will usually call itself recursively
+-- Only applied to types of kind *, hence the newtype is always saturated
+splitRecNewType_maybe (NoteTy _ ty) = splitRecNewType_maybe ty
+splitRecNewType_maybe (PredTy p) = splitRecNewType_maybe (predTypeRep p)
+splitRecNewType_maybe (NewTcApp tc tys)
+ | isRecursiveTyCon tc
+ = ASSERT( tys `lengthIs` tyConArity tc && isNewTyCon tc )
+ -- The assert should hold because splitRecNewType_maybe
+ -- should only be applied to *types* (of kind *)
+ Just (new_type_rhs tc tys)
+splitRecNewType_maybe other = Nothing
+
+-----------------------------
+newTypeRep :: TyCon -> [Type] -> Type
+-- A local helper function (not exported)
+-- Expands *the outermoset level of* a newtype application to
+-- *either* a vanilla TyConApp (recursive newtype, or non-saturated)
+-- *or* the newtype representation (otherwise), meaning the
+-- type written in the RHS of the newtype decl,
+-- which may itself be a newtype
+--
+-- Example: newtype R = MkR S
+-- newtype S = MkS T
+-- newtype T = MkT (T -> T)
+-- newTypeRep on R gives NewTcApp S
+-- on S gives NewTcApp T
+-- on T gives TyConApp T
+--
+-- 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_rhs tc tys
+ | otherwise
+ = TyConApp tc tys