[project @ 2003-07-29 16:31:39 by igloo]
[ghc-hetmet.git] / ghc / compiler / types / Type.lhs
index ad7d1c9..9a9fae2 100644 (file)
@@ -18,11 +18,6 @@ module Type (
        isTypeKind, isAnyTypeKind,
        funTyCon,
 
-        usageKindCon,                                  -- :: KX
-        usageTypeKind,                                 -- :: KX
-        usOnceTyCon, usManyTyCon,                      -- :: $
-        usOnce, usMany,                                        -- :: $
-
         -- exports from this module:
         hasMoreBoxityInfo, defaultKind,
 
@@ -65,7 +60,7 @@ module Type (
        tidyTopType,   tidyPred,
 
        -- Comparison
-       eqType, eqKind, eqUsage, 
+       eqType, eqKind, 
 
        -- Seq
        seqType, seqTypes
@@ -85,12 +80,12 @@ import {-# SOURCE #-}       PprType( pprType )      -- Only called in debug messages
 import {-# SOURCE #-}   Subst  ( substTyWith )
 
 -- friends:
-import Var     ( TyVar, tyVarKind, tyVarName, setTyVarName )
+import Var     ( Id, TyVar, tyVarKind, tyVarName, setTyVarName )
 import VarEnv
 import VarSet
 
 import Name    ( NamedThing(..), mkInternalName, tidyOccName )
-import Class   ( classTyCon )
+import Class   ( Class, classTyCon )
 import TyCon   ( TyCon, isRecursiveTyCon, isPrimTyCon,
                  isUnboxedTupleTyCon, isUnLiftedTyCon,
                  isFunTyCon, isNewTyCon, newTyConRep,
@@ -104,7 +99,7 @@ import CmdLineOpts   ( opt_DictsStrict )
 import SrcLoc          ( noSrcLoc )
 import PrimRep         ( PrimRep(..) )
 import Unique          ( Uniquable(..) )
-import Util            ( mapAccumL, seqList, lengthIs )
+import Util            ( mapAccumL, seqList, lengthIs, snocView )
 import Outputable
 import UniqSet         ( sizeUniqSet )         -- Should come via VarSet
 import Maybe           ( isJust )
@@ -224,14 +219,11 @@ splitAppTy_maybe :: Type -> Maybe (Type, Type)
 splitAppTy_maybe (FunTy ty1 ty2)   = Just (TyConApp funTyCon [ty1], ty2)
 splitAppTy_maybe (AppTy ty1 ty2)   = Just (ty1, ty2)
 splitAppTy_maybe (NoteTy _ ty)     = splitAppTy_maybe ty
-splitAppTy_maybe (SourceTy p)        = splitAppTy_maybe (sourceTypeRep p)
-splitAppTy_maybe (TyConApp tc [])  = Nothing
-splitAppTy_maybe (TyConApp tc tys) = split tys []
-                           where
-                              split [ty2]    acc = Just (TyConApp tc (reverse acc), ty2)
-                              split (ty:tys) acc = split tys (ty:acc)
-
-splitAppTy_maybe other           = Nothing
+splitAppTy_maybe (SourceTy p)      = splitAppTy_maybe (sourceTypeRep p)
+splitAppTy_maybe (TyConApp tc tys) = case snocView tys of
+                                       Nothing -> Nothing
+                                       Just (tys',ty') -> Just (TyConApp tc tys', ty')
+splitAppTy_maybe other            = Nothing
 
 splitAppTy :: Type -> (Type, Type)
 splitAppTy ty = case splitAppTy_maybe ty of
@@ -243,7 +235,7 @@ splitAppTys ty = split ty ty []
   where
     split orig_ty (AppTy ty arg)        args = split ty ty (arg:args)
     split orig_ty (NoteTy _ ty)         args = split orig_ty ty args
-    split orig_ty (SourceTy p)            args = split orig_ty (sourceTypeRep p) args
+    split orig_ty (SourceTy p)          args = split orig_ty (sourceTypeRep p) args
     split orig_ty (FunTy ty1 ty2)       args = ASSERT( null args )
                                               (TyConApp funTyCon [], [ty1,ty2])
     split orig_ty (TyConApp tc tc_args) args = (TyConApp tc [], tc_args ++ args)
@@ -480,7 +472,13 @@ dropForAlls ty = snd (splitForAllTys ty)
 
 -- (mkPiType now in CoreUtils)
 
-Applying a for-all to its arguments.  Lift usage annotation as required.
+applyTy, applyTys
+~~~~~~~~~~~~~~~~~
+Instantiate a for-all type with one or more type arguments.
+Used when we have a polymorphic function applied to type args:
+       f t1 t2
+Then we use (applyTys type-of-f [t1,t2]) to compute the type of
+the expression. 
 
 \begin{code}
 applyTy :: Type -> Type -> Type
@@ -490,17 +488,32 @@ applyTy (ForAllTy tv ty) arg = substTyWith [tv] [arg] ty
 applyTy other           arg = panic "applyTy"
 
 applyTys :: Type -> [Type] -> Type
-applyTys fun_ty arg_tys
- = substTyWith tvs arg_tys ty
- where
-   (mu, tvs, ty) = split fun_ty arg_tys
-   
-   split fun_ty               []         = (Nothing, [], fun_ty)
-   split (NoteTy _ fun_ty)    args       = split fun_ty args
-   split (SourceTy p)        args       = split (sourceTypeRep p) args
-   split (ForAllTy tv fun_ty) (arg:args) = case split fun_ty args of
-                                                 (mu, tvs, ty) -> (mu, tv:tvs, ty)
-   split other_ty             args       = panic "applyTys"
+-- This function is interesting because 
+--     a) the function may have more for-alls than there are args
+--     b) less obviously, it may have fewer for-alls
+-- For case (b) think of 
+--     applyTys (forall a.a) [forall b.b, Int]
+-- This really can happen, via dressing up polymorphic types with newtype
+-- clothing.  Here's an example:
+--     newtype R = R (forall a. a->a)
+--     foo = case undefined :: R of
+--             R f -> f ()
+
+applyTys orig_fun_ty []      = orig_fun_ty
+applyTys orig_fun_ty arg_tys 
+  | n_tvs == n_args    -- The vastly common case
+  = substTyWith tvs arg_tys rho_ty
+  | n_tvs > n_args     -- Too many for-alls
+  = substTyWith (take n_args tvs) arg_tys 
+               (mkForAllTys (drop n_args tvs) rho_ty)
+  | otherwise          -- Too many type args
+  = ASSERT2( n_tvs > 0, pprType orig_fun_ty )  -- Zero case gives infnite loop!
+    applyTys (substTyWith tvs (take n_tvs arg_tys) rho_ty)
+            (drop n_tvs arg_tys)
+  where
+    (tvs, rho_ty) = splitForAllTys orig_fun_ty 
+    n_tvs = length tvs
+    n_args = length arg_tys     
 \end{code}
 
 
@@ -643,8 +656,6 @@ addFreeTyVars ty@(NoteTy (FTVNote _) _)      = ty
 addFreeTyVars ty                            = NoteTy (FTVNote (tyVarsOfType ty)) ty
 \end{code}
 
-
-
 %************************************************************************
 %*                                                                     *
 \subsection{TidyType}
@@ -854,7 +865,6 @@ I don't think this is harmful, but it's soemthing to watch out for.
 \begin{code}
 eqType t1 t2 = eq_ty emptyVarEnv t1 t2
 eqKind  = eqType       -- No worries about looking 
-eqUsage = eqType       -- through source types for these two
 
 -- Look through Notes
 eq_ty env (NoteTy _ t1)       t2                 = eq_ty env t1 t2