HaRe-0.6: tools/base/TI/NewTiMonad.hs
module NewTiMonad(
IM,--TI,KI,
KEnv,
getEnv,getTEnv,getKEnv,getIEnv,getModule,getDefaults,
extendts,extend,extend1,extendkts,extendEnv,extendIEnv,inModule,inEnv,
env,kenv,sch,kindOf,constrain,getConstraints,
(>:),errmap,freshInt
) where
import HsIdent(HsIdentI)
import HsName(ModuleName(..))
import TiTypes
--import TiKinds(Kind,TypeInfo{-,KindConstraint-})
import TiEnv(lookup,extenv1,extenv)
import qualified TiEnv(Env,empty)
import TiInstanceDB(IDB,emptyIdb,extendIdb)
import TiConstraints(Constraints,empty,single,merge)
import MUtils
import Lift
import PrettyPrint(pp)
import MT(MT(..))
import OutputMT
import StateMT
import EnvMT
import ExceptM
import qualified Tree
type TEnv i = TiEnv.Env (HsIdentI i) (Scheme i) -- type of value identifiers
type KEnv i = TiEnv.Env (HsIdentI i) (Kind,TypeInfo i) -- kind of type identifiers
data TiEnv i = Env { inMod::FilePath->ModuleName,
monomorph::Bool, -- use the monomorpism restriction?
defaults::[[Type i]], -- from all default(t1,...,t2)
kenv::KEnv i,
tenv::TEnv i,
idb::IDB i }
emptyEnv = Env (const (Module "nomodule")) True [] TiEnv.empty TiEnv.empty emptyIdb
-- IM should really be an abstract type!
type IM i c = WithOutput c
( WithEnv (TiEnv i)
( WithState Unique
( ExceptM Error )))
--type TI i = IM i (TypeConstraint i)
--type KI i = IM i KindConstraint
type Error = String
type Unique = [Int]
errmap f m = do e <- getEnv
s <- getSt
case withStS s (withEnv e (removeOutput m)) of
Left x -> raise (f x)
Right ((a,t),s) -> setSt_ s >> outputTree t >> return a
run :: TiEnv i -> IM i c a -> Either Error a
run env = removeExcept . withSt [1..] . withEnv env . fmap fst . removeOutput
instance Monad m => Lift (IM i c) m where
lift = either fail return . run emptyEnv
getConstraints :: IM i c a -> IM i d (a, Tree.T c)
getConstraints m = MT.lift (removeOutput m)
typeError :: Error -> IM i c a
typeError err = raise err
constrain :: c -> IM i c ()
constrain c = output c
modEnv :: (TiEnv i -> TiEnv i) -> IM i c a -> IM i c a
modEnv f = inModEnv f
modTEnv f = modEnv (\env@Env{tenv=e}->env{tenv=f e})
modKEnv f = modEnv (\env@Env{kenv=e}->env{kenv=f e})
modIEnv f = modEnv (\env@Env{idb=e}->env{idb=f e})
getTEnv :: IM i c (TEnv i)
getTEnv = tenv # getEnv
getKEnv :: IM i c (KEnv i)
getKEnv = kenv # getEnv
getIEnv :: IM i c (IDB i)
getIEnv = idb # getEnv
getModule :: IM i c (FilePath->ModuleName)
getModule = inMod # getEnv
getDefaults :: IM i c [[Type i]]
getDefaults = defaults # getEnv
extend1 x t = modTEnv (extenv1 x t)
extend x = modTEnv (extenv x)
extendts ts = extend [(x,t)|x:>:t<-ts]
extendk1 x t = modKEnv (extenv1 x t)
extendk x = modKEnv (extenv x)
extendkts ts = extendk [(x,t)|x:>:t<-ts]
extendEnv (ks, ts) = extendkts ks . extendts ts
extendEnv' (ks, ts) = extendk ks . extend ts
extendIEnv x = modIEnv (extendIdb x)
inModule m d = modEnv (\env->env{inMod=m,defaults=d})
env proj x =
do env <- getEnv
case TiEnv.lookup (proj env) x of
Nothing -> typeError ("Not in scope: "++pp x{-++" in "++show (proj env)-})
Just sch -> return sch
sch x = env tenv x
kindOf x = fst # env kenv x
freshInt :: IM i c Int
freshInt = head # updSt tail
infix 4 >:
(>:) :: e -> t -> IM i c (Typing e t)
e >: t = return (e :>: t)