module DDC.Type.Transform.SpreadT (SpreadT(..)) where import DDC.Type.Exp import DDC.Type.Env (Env) import qualified DDC.Type.Env as Env import qualified DDC.Type.Sum as T class SpreadT (c :: * -> *) where -- | Spread type annotations from variable binders in to the bound -- occurrences. spreadT :: forall n. Ord n => Env n -> c n -> c n instance SpreadT Type where spreadT kenv tt = case tt of TVar u -> TVar $ spreadT kenv u TCon tc -> TCon $ spreadT kenv tc TForall b t -> let b' = spreadT kenv b in TForall b' $ spreadT (Env.extend b' kenv) t TApp t1 t2 -> TApp (spreadT kenv t1) (spreadT kenv t2) TSum ss -> TSum (spreadT kenv ss) instance SpreadT TypeSum where spreadT kenv ss = T.fromList (spreadT kenv $ T.kindOfSum ss) $ map (spreadT kenv) $ T.toList ss instance SpreadT Bind where spreadT kenv bb = case bb of BName n t -> BName n (spreadT kenv t) BAnon t -> BAnon (spreadT kenv t) BNone t -> BNone (spreadT kenv t) instance SpreadT Bound where spreadT kenv uu | Just t' <- Env.lookup uu kenv = case uu of UIx ix _ -> UIx ix t' UPrim n _ -> UPrim n t' UName n _ -> if Env.isPrim kenv n then UPrim n t' else UName n t' | otherwise = uu instance SpreadT TyCon where spreadT kenv tc = case tc of TyConBound u -> TyConBound (spreadT kenv u) _ -> tc