[project @ 1996-04-30 17:34:02 by partain]
[ghc-hetmet.git] / ghc / compiler / types / Type.lhs
index 0d25048..5c06b0f 100644 (file)
@@ -6,7 +6,8 @@ module Type (
        mkTyVarTy, mkTyVarTys,
        getTyVar, getTyVar_maybe, isTyVarTy,
        mkAppTy, mkAppTys, splitAppTy,
-       mkFunTy, mkFunTys, splitFunTy, getFunTy_maybe,
+       mkFunTy, mkFunTys, splitFunTy, splitFunTyWithDictsAsArgs,
+       getFunTy_maybe,
        mkTyConTy, getTyCon_maybe, applyTyCon,
        mkSynTy,
        mkForAllTy, mkForAllTys, getForAllTy_maybe, splitForAllTy,
@@ -31,22 +32,25 @@ module Type (
 
        isTauTy,
 
-       tyVarsOfType, tyVarsOfTypes, getTypeKind
-
-
-) where
+       tyVarsOfType, tyVarsOfTypes, typeKind
+    ) where
 
 import Ubiq
 import IdLoop   -- for paranoia checking
 import TyLoop   -- for paranoia checking
 import PrelLoop  -- for paranoia checking
 
+-- ToDo:rm 
+--import PprType       ( pprGenType ) -- ToDo: rm
+--import PprStyle ( PprStyle(..) )
+--import Util  ( pprPanic )
+
 -- friends:
-import Class   ( getClassSig, getClassOpLocalType, GenClass{-instances-} )
+import Class   ( classSig, classOpLocalType, GenClass{-instances-} )
 import Kind    ( mkBoxedTypeKind, resultKind )
-import TyCon   ( mkFunTyCon, mkTupleTyCon, isFunTyCon, isPrimTyCon, isDataTyCon, tyConArity,
+import TyCon   ( mkFunTyCon, mkTupleTyCon, isFunTyCon, isPrimTyCon, isDataTyCon, isSynTyCon, tyConArity,
                  tyConKind, tyConDataCons, getSynTyConDefn, TyCon )
-import TyVar   ( getTyVarKind, GenTyVar{-instances-}, GenTyVarSet(..),
+import TyVar   ( tyVarKind, GenTyVar{-instances-}, GenTyVarSet(..),
                  emptyTyVarSet, unionTyVarSets, minusTyVarSet,
                  unitTyVarSet, nullTyVarEnv, lookupTyVarEnv,
                  addOneToTyVarEnv, TyVarEnv(..) )
@@ -75,7 +79,7 @@ data GenType tyvar uvar       -- Parameterised over type and usage variables
        (GenType tyvar uvar)
 
   | TyConTy    -- Constants of a specified kind
-       TyCon 
+       TyCon   -- Must *not* be a SynTyCon
        (GenUsage uvar) -- Usage gives uvar of the full application,
                        -- iff the full application is of kind Type
                        -- c.f. the Usage field in TyVars
@@ -141,15 +145,15 @@ expandTy (DictTy clas ty u)
 
                -- A tuple of 'em
                -- Note: length of all_arg_tys can be 0 if the class is
-               --       _CCallable, _CReturnable (and anything else
+               --       CCallable, CReturnable (and anything else
                --       *really weird* that the user writes).
   where
-    (tyvar, super_classes, ops) = getClassSig clas
+    (tyvar, super_classes, ops) = classSig clas
     super_dict_tys = map mk_super_ty super_classes
     class_op_tys   = map mk_op_ty ops
     all_arg_tys    = super_dict_tys ++ class_op_tys
     mk_super_ty sc = DictTy sc ty usageOmega
-    mk_op_ty   op = instantiateTy [(tyvar,ty)] (getClassOpLocalType op)
+    mk_op_ty   op = instantiateTy [(tyvar,ty)] (classOpLocalType op)
 
 expandTy ty = ty
 \end{code}
@@ -207,25 +211,48 @@ getFunTy_maybe (AppTy (AppTy (TyConTy tycon _) arg) res)
 getFunTy_maybe (SynTy _ _ t)        = getFunTy_maybe t
 getFunTy_maybe other               = Nothing
 
-splitFunTy :: GenType t u -> ([GenType t u], GenType t u)
+splitFunTy               :: GenType t u -> ([GenType t u], GenType t u)
+splitFunTyWithDictsAsArgs :: Type       -> ([Type], Type)
+  -- splitFunTy *must* have the general type given, which
+  -- means it *can't* do the DictTy jiggery-pokery that
+  -- *is* sometimes required.  The relationship between these
+  -- two functions is like that between eqTy and eqSimpleTy.
+
 splitFunTy t = go t []
   where
     go (FunTy arg res _) ts = go res (arg:ts)
     go (AppTy (AppTy (TyConTy tycon _) arg) res) ts
-       | isFunTyCon tycon
-       = go res (arg:ts)
-    go (SynTy _ _ t) ts
-       = go t ts
-    go t ts
-       = (reverse ts, t)
+       | isFunTyCon tycon  = go res (arg:ts)
+    go (SynTy _ _ t) ts     = go t ts
+    go t ts                = (reverse ts, t)
+
+splitFunTyWithDictsAsArgs t = go t []
+  where
+    go (FunTy arg res _) ts = go res (arg:ts)
+    go (AppTy (AppTy (TyConTy tycon _) arg) res) ts
+       | isFunTyCon tycon  = go res (arg:ts)
+    go (SynTy _ _ t) ts     = go t ts
+
+       -- For a dictionary type we try expanding it to see if we get a simple
+       -- function; if so we thunder on; if not we throw away the expansion.
+    go t@(DictTy _ _ _) ts | null ts'  = (reverse ts, t)
+                          | otherwise = (reverse ts ++ ts', t')
+                          where
+                            (ts', t') = go (expandTy t) []
+
+    go t ts = (reverse ts, t)
 \end{code}
 
 \begin{code}
 -- NB applyTyCon puts in usageOmega, for now at least
-mkTyConTy tycon = TyConTy tycon usageOmega
+mkTyConTy tycon
+  = ASSERT(not (isSynTyCon tycon))
+    TyConTy tycon usageOmega
 
 applyTyCon :: TyCon -> [GenType t u] -> GenType t u
-applyTyCon tycon tys = foldl AppTy (TyConTy tycon usageOmega) tys
+applyTyCon tycon tys
+  = ASSERT (not (isSynTyCon tycon))
+    foldl AppTy (TyConTy tycon usageOmega) tys
 
 getTyCon_maybe :: GenType t u -> Maybe TyCon
 getTyCon_maybe (TyConTy tycon _) = Just tycon
@@ -235,7 +262,8 @@ getTyCon_maybe other_ty              = Nothing
 
 \begin{code}
 mkSynTy syn_tycon tys
-  = SynTy syn_tycon tys (instantiateTauTy (zipEqual tyvars tys) body)
+  = ASSERT(isSynTyCon syn_tycon)
+    SynTy syn_tycon tys (instantiateTauTy (zipEqual tyvars tys) body)
   where
     (tyvars, body) = getSynTyConDefn syn_tycon
 \end{code}
@@ -368,7 +396,7 @@ getAppDataTyCon ty
   = case maybeAppDataTyCon ty of
       Just stuff -> stuff
 #ifdef DEBUG
-      Nothing    -> panic "Type.getAppDataTyCon" -- (ppr PprShowAll ty)
+      Nothing    -> panic "Type.getAppDataTyCon: " -- (pprGenType PprShowAll ty)
 #endif
 
 
@@ -400,15 +428,15 @@ mkSigmaTy tyvars theta tau = mkForAllTys tyvars (mkRhoTy theta tau)
 Finding the kind of a type
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 \begin{code}
-getTypeKind :: GenType (GenTyVar any) u -> Kind
-getTypeKind (TyVarTy tyvar)            = getTyVarKind tyvar
-getTypeKind (TyConTy tycon usage)      = tyConKind tycon
-getTypeKind (SynTy _ _ ty)             = getTypeKind ty
-getTypeKind (FunTy fun arg _)          = mkBoxedTypeKind
-getTypeKind (DictTy clas arg _)                = mkBoxedTypeKind
-getTypeKind (AppTy fun arg)            = resultKind (getTypeKind fun)
-getTypeKind (ForAllTy _ _)             = mkBoxedTypeKind
-getTypeKind (ForAllUsageTy _ _ _)      = mkBoxedTypeKind
+typeKind :: GenType (GenTyVar any) u -> Kind
+typeKind (TyVarTy tyvar)       = tyVarKind tyvar
+typeKind (TyConTy tycon usage) = tyConKind tycon
+typeKind (SynTy _ _ ty)                = typeKind ty
+typeKind (FunTy fun arg _)     = mkBoxedTypeKind
+typeKind (DictTy clas arg _)   = mkBoxedTypeKind
+typeKind (AppTy fun arg)       = resultKind (typeKind fun)
+typeKind (ForAllTy _ _)                = mkBoxedTypeKind
+typeKind (ForAllUsageTy _ _ _) = mkBoxedTypeKind
 \end{code}
 
 
@@ -683,8 +711,16 @@ eqTy t1 t2 =
     -- Expand t2 just in case t1 matches that version
     eq tve uve t1 (AppTy (AppTy (TyConTy mkFunTyCon u2) f2) a2)
 
-  eq tve uve (DictTy c1 t1 u1) (DictTy c2 t2 u2) =
-    c1 == c2 && eq tve uve t1 t2 && eqUsage uve u1 u2
+  eq tve uve (DictTy c1 t1 u1) (DictTy c2 t2 u2) 
+    | c1 == c2 
+    = eq tve uve t1 t2 && eqUsage uve u1 u2
+       -- NB we use a guard for c1==c2 so that if they aren't equal we
+       -- fall through into expanding the type.  Why?  Because brain-dead
+       -- people might write
+       --      class Foo a => Baz a where {}
+       -- and that means that a Foo dictionary and a Baz dictionary are identical
+       -- Sigh.  Let's hope we don't spend too much time in here!
+
   eq tve uve t1@(DictTy _ _ _) t2 =
     eq tve uve (expandTy t1) t2  -- Expand the dictionary and try again
   eq tve uve t1 t2@(DictTy _ _ _) =