mkFunTy, mkFunTys, splitFunTy, splitFunTy_maybe, splitFunTys,
funResultTy, funArgTy, zipFunTys, isFunTy,
- mkTyConApp, mkTyConTy,
+ mkGenTyConApp, mkTyConApp, mkTyConTy,
tyConAppTyCon, tyConAppArgs,
splitTyConApp_maybe, splitTyConApp,
import VarEnv
import VarSet
-import Name ( NamedThing(..), mkLocalName, tidyOccName )
+import Name ( NamedThing(..), mkInternalName, tidyOccName )
import Class ( classTyCon )
import TyCon ( TyCon, isRecursiveTyCon, isPrimTyCon,
isUnboxedTupleTyCon, isUnLiftedTyCon,
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
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
| 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
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
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