X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Ftypes%2FTypeRep.lhs;h=fafbaab1d27df759b5ad8d84504350ee0f9070fe;hp=52e12bf56b664c8a83376485230019135606d58a;hb=d2ce0f52d42edf32bb9f13796e6ba6edba8bd516;hpb=125502965ee73734980b19c6cbcc5e6a43a860a8 diff --git a/compiler/types/TypeRep.lhs b/compiler/types/TypeRep.lhs index 52e12bf..fafbaab 100644 --- a/compiler/types/TypeRep.lhs +++ b/compiler/types/TypeRep.lhs @@ -7,6 +7,7 @@ \begin{code} -- We expose the relevant stuff from this module via the Type module {-# OPTIONS_HADDOCK hide #-} +{-# LANGUAGE DeriveDataTypeable #-} module TypeRep ( TyThing(..), @@ -15,12 +16,12 @@ module TypeRep ( Kind, ThetaType, -- Synonyms - funTyCon, + funTyCon, funTyConName, -- Pretty-printing pprType, pprParendType, pprTypeApp, pprTyThing, pprTyThingCategory, - pprPred, pprTheta, pprForAll, pprThetaArrow, pprClassPred, + pprPred, pprEqPred, pprTheta, pprForAll, pprThetaArrow, pprClassPred, -- Kinds liftedTypeKind, unliftedTypeKind, openTypeKind, @@ -53,7 +54,6 @@ import {-# SOURCE #-} DataCon( DataCon, dataConName ) -- friends: import Var import Name -import OccName import BasicTypes import TyCon import Class @@ -62,6 +62,9 @@ import Class import PrelNames import Outputable import FastString + +-- libraries +import Data.Data hiding ( TyCon ) \end{code} ---------------------- @@ -156,6 +159,7 @@ data Type -- of a 'FunTy' (unlike the 'PredType' constructors 'ClassP' or 'IParam') -- See Note [PredTy], and Note [Equality predicates] + deriving (Data, Typeable) -- | The key type representing kinds in the compiler. -- Invariant: a kind is always in one of these forms: @@ -197,6 +201,7 @@ data PredType = ClassP Class [Type] -- ^ Class predicate e.g. @Eq a@ | IParam (IPName Name) Type -- ^ Implicit parameter e.g. @?x :: Int@ | EqPred Type Type -- ^ Equality predicate e.g @ty1 ~ ty2@ + deriving (Data, Typeable) -- | A collection of 'PredType's type ThetaType = [PredType] @@ -305,14 +310,11 @@ funTyCon = mkFunTyCon funTyConName (mkArrowKinds [argTypeKind, openTypeKind] lif tySuperKindTyCon = mkSuperKindTyCon tySuperKindTyConName coSuperKindTyCon = mkSuperKindTyCon coSuperKindTyConName -liftedTypeKindTyCon = mkKindTyCon liftedTypeKindTyConName -openTypeKindTyCon = mkKindTyCon openTypeKindTyConName -unliftedTypeKindTyCon = mkKindTyCon unliftedTypeKindTyConName -ubxTupleKindTyCon = mkKindTyCon ubxTupleKindTyConName -argTypeKindTyCon = mkKindTyCon argTypeKindTyConName - -mkKindTyCon :: Name -> TyCon -mkKindTyCon name = mkVoidPrimTyCon name tySuperKind 0 +liftedTypeKindTyCon = mkKindTyCon liftedTypeKindTyConName tySuperKind +openTypeKindTyCon = mkKindTyCon openTypeKindTyConName tySuperKind +unliftedTypeKindTyCon = mkKindTyCon unliftedTypeKindTyConName tySuperKind +ubxTupleKindTyCon = mkKindTyCon ubxTupleKindTyConName tySuperKind +argTypeKindTyCon = mkKindTyCon argTypeKindTyConName tySuperKind -------------------------- -- ... and now their names @@ -432,17 +434,38 @@ pprTypeApp tc tys = ppr_type_app TopPrec (getName tc) tys pprPred :: PredType -> SDoc pprPred (ClassP cls tys) = pprClassPred cls tys pprPred (IParam ip ty) = ppr ip <> dcolon <> pprType ty -pprPred (EqPred ty1 ty2) = sep [ppr ty1, nest 2 (ptext (sLit "~")), ppr ty2] +pprPred (EqPred ty1 ty2) = pprEqPred (ty1,ty2) + +pprEqPred :: (Type,Type) -> SDoc +pprEqPred (ty1,ty2) = sep [ ppr_type FunPrec ty1 + , nest 2 (ptext (sLit "~")) + , ppr_type FunPrec ty2] + -- Precedence looks like (->) so that we get + -- Maybe a ~ Bool + -- (a->a) ~ Bool + -- Note parens on the latter! + pprClassPred :: Class -> [Type] -> SDoc pprClassPred clas tys = ppr_type_app TopPrec (getName clas) tys pprTheta :: ThetaType -> SDoc -pprTheta theta = parens (sep (punctuate comma (map pprPred theta))) +-- pprTheta [pred] = pprPred pred -- I'm in two minds about this +pprTheta theta = parens (sep (punctuate comma (map pprPred theta))) pprThetaArrow :: ThetaType -> SDoc -pprThetaArrow theta - | null theta = empty - | otherwise = parens (sep (punctuate comma (map pprPred theta))) <+> ptext (sLit "=>") +pprThetaArrow [] = empty +pprThetaArrow [pred] + | noParenPred pred = pprPred pred <+> darrow +pprThetaArrow preds = parens (sep (punctuate comma (map pprPred preds))) <+> darrow + +noParenPred :: PredType -> Bool +-- A predicate that can appear without parens before a "=>" +-- C a => a -> a +-- a~b => a -> b +-- But (?x::Int) => Int -> Int +noParenPred (ClassP {}) = True +noParenPred (EqPred {}) = True +noParenPred (IParam {}) = False ------------------ instance Outputable Type where @@ -462,8 +485,11 @@ pprKind = pprType pprParendKind = pprParendType ppr_type :: Prec -> Type -> SDoc -ppr_type _ (TyVarTy tv) = ppr tv -ppr_type _ (PredTy pred) = ifPprDebug (ptext (sLit "")) <> (ppr pred) +ppr_type _ (TyVarTy tv) -- Note [Infix type variables] + | isSymOcc (getOccName tv) = parens (ppr tv) + | otherwise = ppr tv +ppr_type p (PredTy pred) = maybeParen p TyConPrec $ + ifPprDebug (ptext (sLit "")) <> (ppr pred) ppr_type p (TyConApp tc tys) = ppr_tc_app p tc tys ppr_type p (AppTy t1 t2) = maybeParen p TyConPrec $ @@ -553,3 +579,24 @@ pprTvBndr tv | isLiftedTypeKind kind = ppr tv kind = tyVarKind tv \end{code} +Note [Infix type variables] +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In Haskell 98 you can say + + f :: (a ~> b) -> b + +and the (~>) is considered a type variable. However, the type +pretty-printer in this module will just see (a ~> b) as + + App (App (TyVarTy "~>") (TyVarTy "a")) (TyVarTy "b") + +So it'll print the type in prefix form. To avoid confusion we must +remember to parenthesise the operator, thus + + (~>) a b -> b + +See Trac #2766. + + + +