[project @ 2000-03-23 17:45:17 by simonpj]
[ghc-hetmet.git] / ghc / compiler / types / Type.lhs
index 8271ce3..33d59ba 100644 (file)
@@ -29,14 +29,16 @@ module Type (
 
        mkAppTy, mkAppTys, splitAppTy, splitAppTys, splitAppTy_maybe,
 
-       mkFunTy, mkFunTys, splitFunTy_maybe, splitFunTys, splitFunTysN,
+       mkFunTy, mkFunTys, splitFunTy, splitFunTy_maybe, splitFunTys, splitFunTysN,
        funResultTy, funArgTy, zipFunTys,
 
        mkTyConApp, mkTyConTy, splitTyConApp_maybe,
        splitAlgTyConApp_maybe, splitAlgTyConApp, 
-       mkDictTy, splitDictTy_maybe, isDictTy,
+       mkDictTy, mkPredTy, splitPredTy_maybe, splitDictTy_maybe, isDictTy,
 
-       mkSynTy, isSynTy, deNoteType, repType, splitNewType_maybe,
+       mkSynTy, isSynTy, deNoteType, 
+
+       repType, splitRepFunTys, splitNewType_maybe, typePrimRep,
 
         UsageAnn(..), mkUsgTy, isUsgTy{- dont use -}, isNotUsgTy, splitUsgTy, unUsgTy, tyUsg,
         mkUsForAllTy, mkUsForAllTys, splitUsForAllTys, substUsTy,
@@ -44,18 +46,18 @@ module Type (
        mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys, 
        isForAllTy, applyTy, applyTys, mkPiType,
 
-       TauType, RhoType, SigmaType, ThetaType,
-       isTauTy,
-       mkRhoTy, splitRhoTy,
+       TauType, RhoType, SigmaType, PredType(..), ThetaType,
+       ClassPred, ClassContext, mkClassPred,
+       getClassTys_maybe, ipName_maybe, classesToPreds, classesOfPreds,
+       isTauTy, mkRhoTy, splitRhoTy,
        mkSigmaTy, splitSigmaTy,
 
        -- Lifting and boxity
        isUnLiftedType, isUnboxedType, isUnboxedTupleType, isAlgType, isDataType, isNewType,
-       typePrimRep,
 
        -- Free variables
-       tyVarsOfType, tyVarsOfTypes, namesOfType, typeKind,
-       addFreeTyVars,
+       tyVarsOfType, tyVarsOfTypes, tyVarsOfPred, tyVarsOfTheta,
+       namesOfType, typeKind, addFreeTyVars,
 
        -- Tidying up for printing
        tidyType,     tidyTypes,
@@ -77,18 +79,18 @@ import TypeRep
 
 -- Other imports:
 
-import {-# SOURCE #-}  DataCon( DataCon, dataConType )
-import {-# SOURCE #-}  PprType( pprType )      -- Only called in debug messages
+import {-# SOURCE #-}  DataCon( DataCon, dataConRepType )
+import {-# SOURCE #-}  PprType( pprType, pprPred )     -- Only called in debug messages
 import {-# SOURCE #-}   Subst  ( mkTyVarSubst, substTy )
 
 -- friends:
-import Var     ( TyVar, IdOrTyVar, UVar,
+import Var     ( TyVar, Var, UVar,
                  tyVarKind, tyVarName, setTyVarName, isId, idType,
                )
 import VarEnv
 import VarSet
 
-import Name    ( NamedThing(..), mkLocalName, tidyOccName,
+import Name    ( Name, NamedThing(..), mkLocalName, tidyOccName
                )
 import NameSet
 import Class   ( classTyCon, Class )
@@ -234,6 +236,10 @@ mkFunTy arg res = FunTy arg res
 mkFunTys :: [Type] -> Type -> Type
 mkFunTys tys ty = foldr FunTy ty tys
 
+splitFunTy :: Type -> (Type, Type)
+splitFunTy (FunTy arg res) = (arg, res)
+splitFunTy (NoteTy _ ty)   = splitFunTy ty
+
 splitFunTy_maybe :: Type -> Maybe (Type, Type)
 splitFunTy_maybe (FunTy arg res) = Just (arg, res)
 splitFunTy_maybe (NoteTy _ ty)   = splitFunTy_maybe ty
@@ -329,6 +335,11 @@ tell from the type constructor whether it's a dictionary or not.
 mkDictTy :: Class -> [Type] -> Type
 mkDictTy clas tys = TyConApp (classTyCon clas) tys
 
+mkPredTy :: PredType -> Type
+mkPredTy (Class clas tys) = TyConApp (classTyCon clas) tys
+mkPredTy (IParam n ty)    = NoteTy (IPNote n) ty
+
+{-
 splitDictTy_maybe :: Type -> Maybe (Class, [Type])
 splitDictTy_maybe (TyConApp tc tys) 
   |  maybeToBool maybe_class
@@ -339,6 +350,26 @@ splitDictTy_maybe (TyConApp tc tys)
 
 splitDictTy_maybe (NoteTy _ ty)        = splitDictTy_maybe ty
 splitDictTy_maybe other                = Nothing
+-}
+
+splitPredTy_maybe :: Type -> Maybe PredType
+splitPredTy_maybe (TyConApp tc tys) 
+  |  maybeToBool maybe_class
+  && tyConArity tc == length tys = Just (Class clas tys)
+  where
+     maybe_class = tyConClass_maybe tc
+     Just clas   = maybe_class
+
+splitPredTy_maybe (NoteTy (IPNote n) ty)
+                               = Just (IParam n ty)
+splitPredTy_maybe (NoteTy _ ty)        = splitPredTy_maybe ty
+splitPredTy_maybe other                = Nothing
+
+splitDictTy_maybe :: Type -> Maybe (Class, [Type])
+splitDictTy_maybe ty
+  = case splitPredTy_maybe ty of
+    Just p -> getClassTys_maybe p
+    Nothing -> Nothing
 
 isDictTy :: Type -> Bool
        -- This version is slightly more efficient than (maybeToBool . splitDictTy)
@@ -392,6 +423,8 @@ The reason is that we then get better (shorter) type signatures in
 interfaces.  Notably this plays a role in tcTySigs in TcBinds.lhs.
 
 
+               Representation types
+               ~~~~~~~~~~~~~~~~~~~~
 
 repType looks through 
        (a) for-alls, and
@@ -406,6 +439,12 @@ repType (ForAllTy _ ty)              = repType ty
 repType (TyConApp tc tys) | isNewTyCon tc = repType (new_type_rep tc tys)
 repType other_ty                         = other_ty
 
+
+typePrimRep :: Type -> PrimRep
+typePrimRep ty = case splitTyConApp_maybe (repType ty) of
+                  Just (tc, ty_args) -> tyConPrimRep tc
+                  other              -> PtrRep
+
 splitNewType_maybe :: Type -> Maybe Type
 -- Find the representation of a newtype, if it is one
 -- Looks through multiple levels of newtype
@@ -423,8 +462,15 @@ new_type_rep :: TyCon -> [Type] -> Type
 -- Looks through one layer only
 new_type_rep tc tys 
   = ASSERT( isNewTyCon tc )
-    case splitFunTy_maybe (applyTys (dataConType (head (tyConDataCons tc))) tys) of
+    case splitFunTy_maybe (applyTys (dataConRepType (head (tyConDataCons tc))) tys) of
        Just (rep_ty, _) -> rep_ty
+
+splitRepFunTys :: Type -> ([Type], Type)
+-- Like splitFunTys, but looks through newtypes and for-alls
+splitRepFunTys ty = split [] (repType ty)
+  where
+    split args (FunTy arg res)  = split (arg:args) (repType res)
+    split args ty               = (reverse args, ty)
 \end{code}
 
 
@@ -583,7 +629,7 @@ splitForAllTys ty = case splitUsgTy_maybe ty of
 it is given a type variable or a term variable.
 
 \begin{code}
-mkPiType :: IdOrTyVar -> Type -> Type  -- The more polymorphic version doesn't work...
+mkPiType :: Var -> Type -> Type                -- The more polymorphic version doesn't work...
 mkPiType v ty | isId v    = mkFunTy (idType v) ty
              | otherwise = mkForAllTy v ty
 \end{code}
@@ -628,16 +674,46 @@ argument, however, must still be unannotated.
 %************************************************************************
 %*                                                                     *
 \subsection{Stuff to do with the source-language types}
+
+PredType and ThetaType are used in types for expressions and bindings.
+ClassPred and ClassContext are used in class and instance declarations.
 %*                                                                     *
 %************************************************************************
 
 \begin{code}
 type RhoType   = Type
 type TauType   = Type
-type ThetaType = [(Class, [Type])]
+data PredType  = Class  Class [Type]
+              | IParam Name  Type
+type ThetaType = [PredType]
+type ClassPred = (Class, [Type])
+type ClassContext = [ClassPred]
 type SigmaType = Type
 \end{code}
 
+\begin{code}
+instance Outputable PredType where
+    ppr = pprPred
+\end{code}
+
+\begin{code}
+mkClassPred clas tys = Class clas tys
+
+getClassTys_maybe :: PredType -> Maybe ClassPred
+getClassTys_maybe (Class clas tys) = Just (clas, tys)
+getClassTys_maybe _                = Nothing
+
+ipName_maybe :: PredType -> Maybe Name
+ipName_maybe (IParam n _) = Just n
+ipName_maybe _           = Nothing
+
+classesToPreds cts = map (uncurry Class) cts
+
+classesOfPreds theta = concatMap cvt theta
+    where cvt (Class clas tys) = [(clas, tys)]
+         cvt (IParam _   _  ) = []
+\end{code}
+
 @isTauTy@ tests for nested for-alls.
 
 \begin{code}
@@ -651,14 +727,14 @@ isTauTy other              = False
 \end{code}
 
 \begin{code}
-mkRhoTy :: [(Class, [Type])] -> Type -> Type
-mkRhoTy theta ty = foldr (\(c,t) r -> FunTy (mkDictTy c t) r) ty theta
+mkRhoTy :: [PredType] -> Type -> Type
+mkRhoTy theta ty = foldr (\p r -> FunTy (mkPredTy p) r) ty theta
 
-splitRhoTy :: Type -> ([(Class, [Type])], Type)
+splitRhoTy :: Type -> ([PredType], Type)
 splitRhoTy ty = split ty ty []
  where
-  split orig_ty (FunTy arg res) ts = case splitDictTy_maybe arg of
-                                       Just pair -> split res res (pair:ts)
+  split orig_ty (FunTy arg res) ts = case splitPredTy_maybe arg of
+                                       Just p -> split res res (p:ts)
                                        Nothing   -> (reverse ts, orig_ty)
   split orig_ty (NoteTy _ ty) ts   = split orig_ty ty ts
   split orig_ty ty ts             = (reverse ts, orig_ty)
@@ -669,7 +745,7 @@ splitRhoTy ty = split ty ty []
 \begin{code}
 mkSigmaTy tyvars theta tau = mkForAllTys tyvars (mkRhoTy theta tau)
 
-splitSigmaTy :: Type -> ([TyVar], [(Class, [Type])], Type)
+splitSigmaTy :: Type -> ([TyVar], [PredType], Type)
 splitSigmaTy ty =
   (tyvars, theta, tau)
  where
@@ -715,6 +791,7 @@ tyVarsOfType (NoteTy (FTVNote tvs) ty2) = tvs
 tyVarsOfType (NoteTy (SynNote ty1) ty2)        = tyVarsOfType ty1
 tyVarsOfType (NoteTy (UsgNote _) ty)   = tyVarsOfType ty
 tyVarsOfType (NoteTy (UsgForAll _) ty) = tyVarsOfType ty
+tyVarsOfType (NoteTy (IPNote _) ty)    = tyVarsOfType ty
 tyVarsOfType (FunTy arg res)           = tyVarsOfType arg `unionVarSet` tyVarsOfType res
 tyVarsOfType (AppTy fun arg)           = tyVarsOfType fun `unionVarSet` tyVarsOfType arg
 tyVarsOfType (ForAllTy tyvar ty)       = tyVarsOfType ty `minusVarSet` unitVarSet tyvar
@@ -722,6 +799,13 @@ tyVarsOfType (ForAllTy tyvar ty)   = tyVarsOfType ty `minusVarSet` unitVarSet tyva
 tyVarsOfTypes :: [Type] -> TyVarSet
 tyVarsOfTypes tys = foldr (unionVarSet.tyVarsOfType) emptyVarSet tys
 
+tyVarsOfPred :: PredType -> TyVarSet
+tyVarsOfPred (Class clas tys) = tyVarsOfTypes tys
+tyVarsOfPred (IParam n ty)    = tyVarsOfType ty
+
+tyVarsOfTheta :: ThetaType -> TyVarSet
+tyVarsOfTheta = foldr (unionVarSet . tyVarsOfPred) emptyVarSet
+
 -- Add a Note with the free tyvars to the top of the type
 -- (but under a usage if there is one)
 addFreeTyVars :: Type -> Type
@@ -800,6 +884,7 @@ tidyType env@(tidy_env, subst) ty
     go_note note@(FTVNote ftvs) = note -- No need to tidy the free tyvars
     go_note note@(UsgNote _)    = note  -- Usage annotation is already tidy
     go_note note@(UsgForAll _)  = note  -- Uvar binder is already tidy
+    go_note (IPNote n)         = IPNote (tidyIPName n)
 
 tidyTypes  env tys    = map (tidyType env) tys
 \end{code}
@@ -823,6 +908,12 @@ tidyTopType :: Type -> Type
 tidyTopType ty = tidyType emptyTidyEnv ty
 \end{code}
 
+\begin{code}
+tidyIPName :: Name -> Name
+tidyIPName name
+  = mkLocalName (getUnique name) (getOccName name) noSrcLoc
+\end{code}
+
 
 %************************************************************************
 %*                                                                     *
@@ -870,11 +961,6 @@ isNewType ty = case splitTyConApp_maybe ty of
                        Just (tc, ty_args) -> ASSERT( length ty_args == tyConArity tc )
                                              isNewTyCon tc
                        other              -> False
-
-typePrimRep :: Type -> PrimRep
-typePrimRep ty = case splitTyConApp_maybe ty of
-                  Just (tc, ty_args) -> tyConPrimRep tc
-                  other              -> PtrRep
 \end{code}
 
 
@@ -901,5 +987,6 @@ seqNote :: TyNote -> ()
 seqNote (SynNote ty)  = seqType ty
 seqNote (FTVNote set) = sizeUniqSet set `seq` ()
 seqNote (UsgNote usg) = usg `seq` ()
+seqNote (IPNote nm)    = nm `seq` ()
 \end{code}