[project @ 2002-06-21 13:34:42 by simonpj]
[ghc-hetmet.git] / ghc / compiler / types / Type.lhs
index f901d91..ad7d1c9 100644 (file)
@@ -15,7 +15,7 @@ module Type (
        typeCon,                                        -- :: BX -> KX
        liftedTypeKind, unliftedTypeKind, openTypeKind, -- :: KX
        mkArrowKind, mkArrowKinds,                      -- :: KX -> KX -> KX
-       isTypeKind,
+       isTypeKind, isAnyTypeKind,
        funTyCon,
 
         usageKindCon,                                  -- :: KX
@@ -31,18 +31,18 @@ module Type (
        mkAppTy, mkAppTys, splitAppTy, splitAppTys, splitAppTy_maybe,
 
        mkFunTy, mkFunTys, splitFunTy, splitFunTy_maybe, splitFunTys, 
-       funResultTy, funArgTy, zipFunTys,
+       funResultTy, funArgTy, zipFunTys, isFunTy,
 
-       mkTyConApp, mkTyConTy, 
+       mkGenTyConApp, mkTyConApp, mkTyConTy, 
        tyConAppTyCon, tyConAppArgs, 
        splitTyConApp_maybe, splitTyConApp,
 
        mkSynTy, 
 
-       repType, splitRepFunTys, typePrimRep,
+       repType, typePrimRep,
 
        mkForAllTy, mkForAllTys, splitForAllTy_maybe, splitForAllTys, 
-       applyTy, applyTys, isForAllTy,
+       applyTy, applyTys, isForAllTy, dropForAlls,
 
        -- Source types
        SourceType(..), sourceTypeRep, mkPredTy, mkPredTys,
@@ -85,11 +85,11 @@ import {-# SOURCE #-}       PprType( pprType )      -- Only called in debug messages
 import {-# SOURCE #-}   Subst  ( substTyWith )
 
 -- friends:
-import Var     ( Var, TyVar, tyVarKind, tyVarName, setTyVarName )
+import Var     ( TyVar, tyVarKind, tyVarName, setTyVarName )
 import VarEnv
 import VarSet
 
-import Name    ( NamedThing(..), mkLocalName, tidyOccName )
+import Name    ( NamedThing(..), mkInternalName, tidyOccName )
 import Class   ( classTyCon )
 import TyCon   ( TyCon, isRecursiveTyCon, isPrimTyCon,
                  isUnboxedTupleTyCon, isUnLiftedTyCon,
@@ -101,13 +101,13 @@ import TyCon      ( TyCon, isRecursiveTyCon, isPrimTyCon,
 
 -- others
 import CmdLineOpts     ( opt_DictsStrict )
-import Maybes          ( maybeToBool )
 import SrcLoc          ( noSrcLoc )
 import PrimRep         ( PrimRep(..) )
 import Unique          ( Uniquable(..) )
 import Util            ( mapAccumL, seqList, lengthIs )
 import Outputable
 import UniqSet         ( sizeUniqSet )         -- Should come via VarSet
+import Maybe           ( isJust )
 \end{code}
 
 
@@ -119,20 +119,28 @@ import UniqSet            ( sizeUniqSet )         -- Should come via VarSet
 
 \begin{code}
 hasMoreBoxityInfo :: Kind -> Kind -> Bool
+-- (k1 `hasMoreBoxityInfo` k2) checks that k1 <: k2
 hasMoreBoxityInfo k1 k2
-  | k2 `eqKind` openTypeKind = True
-  | otherwise               = k1 `eqType` k2
+  | k2 `eqKind` openTypeKind = isAnyTypeKind k1
+  | otherwise               = k1 `eqKind` k2
+  where
+
+isAnyTypeKind :: Kind -> Bool
+-- True of kind * and *# and ?
+isAnyTypeKind (TyConApp tc _) = tc == typeCon || tc == openKindCon
+isAnyTypeKind (NoteTy _ k)    = isAnyTypeKind k
+isAnyTypeKind other          = False
+
+isTypeKind :: Kind -> Bool
+-- True of kind * and *#
+isTypeKind (TyConApp tc _) = tc == typeCon
+isTypeKind (NoteTy _ k)    = isTypeKind k
+isTypeKind other          = False
 
 defaultKind :: Kind -> Kind
 -- Used when generalising: default kind '?' to '*'
 defaultKind kind | kind `eqKind` openTypeKind = liftedTypeKind
                 | otherwise                  = kind
-
-isTypeKind :: Kind -> Bool
--- True of kind * and *#
-isTypeKind k = case splitTyConApp_maybe k of
-                Just (tc,[k]) -> tc == typeCon
-                other         -> False
 \end{code}
 
 
@@ -186,8 +194,16 @@ mkAppTy orig_ty1 orig_ty2
     mk_app orig_ty1
   where
     mk_app (NoteTy _ ty1)    = mk_app ty1
-    mk_app (TyConApp tc tys) = mkTyConApp tc (tys ++ [orig_ty2])
+    mk_app (TyConApp tc tys) = mkGenTyConApp tc (tys ++ [orig_ty2])
     mk_app ty1              = AppTy orig_ty1 orig_ty2
+       -- We call mkGenTyConApp because the TyConApp could be an 
+       -- under-saturated type synonym.  GHC allows that; e.g.
+       --      type Foo k = k a -> k a
+       --      type Id x = x
+       --      foo :: Foo Id -> Foo Id
+       --
+       -- Here Id is partially applied in the type sig for Foo,
+       -- but once the type synonyms are expanded all is well
 
 mkAppTys :: Type -> [Type] -> Type
 mkAppTys orig_ty1 []       = orig_ty1
@@ -246,6 +262,9 @@ mkFunTy arg res = FunTy arg res
 mkFunTys :: [Type] -> Type -> Type
 mkFunTys tys ty = foldr FunTy ty tys
 
+isFunTy :: Type -> Bool 
+isFunTy ty = isJust (splitFunTy_maybe ty)
+
 splitFunTy :: Type -> (Type, Type)
 splitFunTy (FunTy arg res) = (arg, res)
 splitFunTy (NoteTy _ ty)   = splitFunTy ty
@@ -295,6 +314,11 @@ funArgTy ty                 = pprPanic "funArgTy" (pprType ty)
 as apppropriate.
 
 \begin{code}
+mkGenTyConApp :: TyCon -> [Type] -> Type
+mkGenTyConApp tc tys
+  | isSynTyCon tc = mkSynTy tc tys
+  | otherwise     = mkTyConApp tc tys
+
 mkTyConApp :: TyCon -> [Type] -> Type
 -- Assumes TyCon is not a SynTyCon; use mkSynTy instead for those
 mkTyConApp tycon tys
@@ -347,7 +371,10 @@ mkSynTy tycon tys
   | n_args == arity    -- Exactly saturated
   = mk_syn tys
   | n_args >  arity    -- Over-saturated
-  = case splitAt arity tys of { (as,bs) -> foldl AppTy (mk_syn as) bs }
+  = case splitAt arity tys of { (as,bs) -> mkAppTys (mk_syn as) bs }
+       -- Its important to use mkAppTys, rather than (foldl AppTy),
+       -- because (mk_syn as) might well return a partially-applied
+       -- type constructor; indeed, usually will!
   | otherwise          -- Un-saturated
   = TyConApp tycon tys
        -- For the un-saturated case we build TyConApp directly
@@ -382,7 +409,6 @@ interfaces.  Notably this plays a role in tcTySigs in TcBinds.lhs.
 
                Representation types
                ~~~~~~~~~~~~~~~~~~~~
-
 repType looks through 
        (a) for-alls, and
        (b) synonyms
@@ -404,12 +430,6 @@ repType (TyConApp tc tys) | isNewTyCon tc && tys `lengthIs` tyConArity tc
                          = repType (newTypeRep tc tys)
 repType ty               = 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)
 
 typePrimRep :: Type -> PrimRep
 typePrimRep ty = case repType ty of
@@ -453,6 +473,9 @@ splitForAllTys ty = split ty ty []
      split orig_ty (NoteTy _ ty)         tvs = split orig_ty ty tvs
      split orig_ty (SourceTy p)                  tvs = split orig_ty (sourceTypeRep p) tvs
      split orig_ty t                     tvs = (reverse tvs, orig_ty)
+
+dropForAlls :: Type -> Type
+dropForAlls ty = snd (splitForAllTys ty)
 \end{code}
 
 -- (mkPiType now in CoreUtils)
@@ -579,12 +602,27 @@ tyVarsOfType :: Type -> TyVarSet
 tyVarsOfType (TyVarTy tv)              = unitVarSet tv
 tyVarsOfType (TyConApp tycon tys)      = tyVarsOfTypes tys
 tyVarsOfType (NoteTy (FTVNote tvs) ty2) = tvs
-tyVarsOfType (NoteTy (SynNote ty1) ty2)        = tyVarsOfType ty1
+tyVarsOfType (NoteTy (SynNote ty1) ty2)        = tyVarsOfType ty2      -- See note [Syn] below
 tyVarsOfType (SourceTy sty)            = tyVarsOfSourceType sty
 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
 
+--                     Note [Syn]
+-- Consider
+--     type T a = Int
+-- What are the free tyvars of (T x)?  Empty, of course!  
+-- Here's the example that Ralf Laemmel showed me:
+--     foo :: (forall a. C u a -> C u a) -> u
+--     mappend :: Monoid u => u -> u -> u
+--
+--     bar :: Monoid u => u
+--     bar = foo (\t -> t `mappend` t)
+-- We have to generalise at the arg to f, and we don't
+-- want to capture the constraint (Monad (C u a)) because
+-- it appears to mention a.  Pretty silly, but it was useful to him.
+
+
 tyVarsOfTypes :: [Type] -> TyVarSet
 tyVarsOfTypes tys = foldr (unionVarSet.tyVarsOfType) emptyVarSet tys
 
@@ -627,7 +665,7 @@ tidyTyVarBndr (tidy_env, subst) tyvar
                    where
                        subst' = extendVarEnv subst tyvar tyvar'
                        tyvar' = setTyVarName tyvar name'
-                       name'  = mkLocalName (getUnique name) occ' noSrcLoc
+                       name'  = mkInternalName (getUnique name) occ' noSrcLoc
                                -- Note: make a *user* tyvar, so it printes nicely
                                -- Could extract src loc, but no need.
   where