+
+data TyNote flexi
+ = SynNote (GenType flexi) -- The unexpanded version of the type synonym; always a TyConApp
+ | FTVNote (GenTyVarSet flexi) -- The free type variables of the noted expression
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Wired-in type constructors
+%* *
+%************************************************************************
+
+We define a few wired-in type constructors here to avoid module knots
+
+\begin{code}
+funTyConName = mkWiredInTyConName funTyConKey pREL_GHC SLIT("->") funTyCon
+funTyCon = mkFunTyCon funTyConName (mkArrowKinds [boxedTypeKind, boxedTypeKind] boxedTypeKind)
+\end{code}
+
+\begin{code}
+mk_kind_name key str = mkGlobalName key pREL_GHC (varOcc str)
+ (LocalDef mkBuiltinSrcLoc NotExported)
+ -- mk_kind_name is a bit of a hack
+ -- The LocalDef means that we print the name without
+ -- a qualifier, which is what we want for these kinds.
+
+boxedKindConName = mk_kind_name boxedKindConKey SLIT("*")
+boxedKindCon = mkKindCon boxedKindConName superKind Boxed
+
+unboxedKindConName = mk_kind_name unboxedKindConKey SLIT("*#")
+unboxedKindCon = mkKindCon unboxedKindConName superKind Unboxed
+
+openKindConName = mk_kind_name openKindConKey SLIT("*?")
+openKindCon = mkKindCon openKindConName superKind Open
+\end{code}
+
+
+%************************************************************************
+%* *
+\subsection{Kinds}
+%* *
+%************************************************************************
+
+\begin{code}
+superKind :: GenKind flexi -- Box, the type of all kinds
+superKind = TyConApp superKindCon []
+
+boxedTypeKind, unboxedTypeKind, openTypeKind :: GenKind flexi
+boxedTypeKind = TyConApp boxedKindCon []
+unboxedTypeKind = TyConApp unboxedKindCon []
+openTypeKind = TyConApp openKindCon []
+
+mkArrowKind :: GenKind flexi -> GenKind flexi -> GenKind flexi
+mkArrowKind = FunTy
+
+mkArrowKinds :: [GenKind flexi] -> GenKind flexi -> GenKind flexi
+mkArrowKinds arg_kinds result_kind = foldr FunTy result_kind arg_kinds
+\end{code}
+
+\begin{code}
+hasMoreBoxityInfo :: GenKind flexi -> GenKind flexi -> Bool
+
+(NoteTy _ k1) `hasMoreBoxityInfo` k2 = k1 `hasMoreBoxityInfo` k2
+k1 `hasMoreBoxityInfo` (NoteTy _ k2) = k1 `hasMoreBoxityInfo` k2
+
+(TyConApp kc1 ts1) `hasMoreBoxityInfo` (TyConApp kc2 ts2)
+ = ASSERT( null ts1 && null ts2 )
+ kc2 `matchesTyCon` kc1 -- NB the reversal of arguments
+
+kind1@(FunTy _ _) `hasMoreBoxityInfo` kind2@(FunTy _ _)
+ = ASSERT( kind1 == kind2 )
+ True
+ -- The two kinds can be arrow kinds; for example when unifying
+ -- (m1 Int) and (m2 Int) we end up unifying m1 and m2, which should
+ -- have the same kind.
+
+-- Other cases are impossible