This module defines the represenation of types, qualified types, type schemes, substitution and various auxiliary types.
module TiTypes(module TiTypes,HsTypeI(..),HsIdentI(..),Kind) where
import Syntax(HsTypeI(..),TI(..),HsIdentI(..),HsFunDeps,
hsTyFun,hsTyApp,hsTyTuple,hsTyCon,hsTyVar,
kstar,base,mapTI,accT)
import List(nub,(\\))
import Maybe(fromMaybe)
import MUtils(collectByFst)
--import TiEnv(Env,range)
import TiKinds(Kind)
import TiNames
import Debug.Trace(trace) -- for debugging
type Type i = HsTypeI i
type Pred i = Type i
data Qual i t = [Pred i] :=> t deriving (Eq,Show,Read)
type QType i = Qual i (Type i)
data Scheme v = Forall [Kinded v] [Kinded v] (QType v)
deriving (Eq,Show,Read) -- Eq??
unQual t = []:=>t
forall' = Forall []
mono t = forall' [] (unQual t)
--uscheme qt = fakeForall (tv qt) qt -- temporary hack!!!
-- where fakeForall vs qt = Forall (map (:>:kstar) vs) qt -- temporary hack!!!
--upscheme t = uscheme (unQual t) -- temporary hack!!!
kuscheme ks qt = forall' (kinded ks (tv qt)) qt
kupscheme ks t = kuscheme ks (unQual t)
funT ts = foldr1 hsTyFun ts -- :: Type
appT ts = foldl1 hsTyApp ts -- :: Type
tupleT ts = hsTyTuple ts -- :: Type
tyvar v = hsTyVar v -- :: Tyvar -> Type
ty (HsVar v) = tyvar v
ty (HsCon c) = hsTyCon c -- :: Type
isVarT (Typ (HsTyVar v)) = Just v
isVarT _ = Nothing
isFunT (Typ (HsTyFun t1 t2)) = Just (t1,t2)
isFunT _ = Nothing
flatAppT t = flat t []
where
flat (Typ (HsTyApp t1 t2)) ts = flat t1 (t2:ts)
flat t ts = (t,ts)
flatConAppT ty =
case flatAppT ty of
(Typ (HsTyCon c),ts) -> Just (HsCon c,ts)
_ -> Nothing
--instName (SrcLoc f l c) = HsVar (Qual (Module "i") (show l++"_"++show c))
--dictName n = HsVar (Qual (Module "d") n) :: QId
--vvar = unqual :: String->VarId
infix 1 :>:
data Typing x t = x :>: t deriving (Eq,Show,Read)
type Assump i = Typing (HsIdentI i) (Scheme i)
type Typed i x = Typing x (Type i)
emap f (e :>: t) = f e:>:t
tdom xts = [x|x:>:_<-xts]
unzipTyped :: [Typing x t] -> Typing [x] [t]
unzipTyped ets = uncurry (:>:) $ unzip [(e,t)|e:>:t<-ets]
zipTyped :: Typing [x] [t] -> [Typing x t]
zipTyped (xs:>:ts) = zipWith (:>:) xs ts
--collectTyped :: Ord x => [Typing x t] -> [Typing x [t]]
collectTyped xts = map (uncurry (:>:)) $ collectByFst [(x,t)|x:>:t<-xts]
type Kinded x = Typing x Kind
kinded1 ks v = v:>:head' [k|HsVar v':>:k<-ks,v'==v] -- not very efficient...
where head' [] = trace ("Bug in TiTypes.kinded1: missing kind info for "++show v) kstar
head' (k:_) = k
kinded ks = map (kinded1 ks)
--type KAssump = Typing Id Kind
type KInfo i = [Typing (HsIdentI i) (TypeInfo i)]
data TypeInfo i
= Data
| Newtype
| Class [Pred i] -- superclasses
[Kinded i] -- parameters
(HsFunDeps Int) -- fun deps (0-based parameter positions)
[Assump i] -- methods
| Synonym [i] (Type i)
| Tyvar
deriving ({-Eq,-}Show,Read)
newtype Subst i = S [(i,Type i)] deriving (Show)
idS = S []
infix 5 +->
v+-> t = S [(v,t)]
extS v t s = compS (v+->t) s
compS s1@(S s1') s2 = S (s1'++s2')
where S s2' = apply s1 s2
domS (S s) = map fst s
varSubst s@(S s') v = fromMaybe (tyvar v) (lookup v s')
applySubst s@(S s') ty@(Typ t) =
case t of
HsTyVar v -> fromMaybe ty (lookup v s')
_ -> base $ mapTI id (applySubst s) t
class TypeVar v => Types v t | t->v where
tmap :: (Type v->Type v) -> t -> t
apply :: Subst v -> t -> t
tv :: t -> Set v
apply = tmap . applySubst
type Set a = [a]
occurs v t = v `elem` tv t
instance Types v t => Types v [t] where
tmap = map . tmap
tv = nub . concatMap tv
instance TypeVar v => Types v (Subst v) where
tmap f (S s') = S [(v,tmap f t)|(v,t)<-s'] -- hmm
tv (S s') = tv (map snd s') -- hmm
instance (Types v t1,Types v t2) => Types v (t1,t2) where
tmap f (t1,t2) = (tmap f t1,tmap f t2)
tv (t1,t2) = nub (tv t1++tv t2)
instance (Types v t1,Types v t2,Types v t3) => Types v (t1,t2,t3) where
tmap f (t1,t2,t3) = (tmap f t1,tmap f t2,tmap f t3)
tv (t1,t2,t3) = nub (tv t1++tv t2++tv t3)
instance Types v t => Types v (Typing x t) where
tmap f (x:>:t) = x:>:tmap f t
tv (x:>:t) = tv t
instance Functor (Typing x) where
fmap f (x:>:t) = x:>:f t -- hmm
instance TypeVar v => Types v (Type v) where
tmap = id
tv (Typ t) =
case t of
HsTyVar v -> [v]
HsTyForall vs ps t -> tv (ps,t) \\ vs
_ -> nub $ accT ((++) . tv) t []
instance TypeVar v => Types v (Scheme v) where
apply s (Forall ags gs qt) = Forall ags gs (apply (restrict s (tdom (ags++gs))) qt)
tmap f (Forall ags gs qt) = Forall ags gs (tmap f qt) -- hmm
tv (Forall ags gs qt) = tv qt \\ tdom (ags++gs)
restrict (S s) gs = S [s1|s1@(v,_)<-s,v `notElem` gs]
instance Types v t => Types v (Qual v t) where
tmap f (ps:=>t) = tmap f ps:=>tmap f t
tv (ps:=>t) = tv (ps,t)
{-
instance Types v info => Types v (Env key info) where
tmap = fmap . tmap
tv = tv . range
-}