+++ /dev/null
-%
-% (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
-%
-\section[BackSubst]{Back substitution functions}
-
-This module applies a typechecker substitution over the whole abstract
-syntax.
-
-\begin{code}
-#include "HsVersions.h"
-
-module BackSubst (
- applyTcSubstToBinds,
-
- -- and to make the interface self-sufficient...
- Subst, Binds, MonoBinds, Id, TypecheckedPat
- ) where
-
-IMPORT_Trace -- ToDo: rm (debugging)
-import Outputable
-import Pretty
-
-import AbsSyn
-import AbsUniType ( getTyVar )
-import TcMonad
-import Util
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[BackSubst-Binds]{Running a substitution over @Binds@}
-%* *
-%************************************************************************
-
-\begin{code}
-applyTcSubstToBinds :: TypecheckedBinds -> NF_TcM TypecheckedBinds
-
-applyTcSubstToBinds EmptyBinds = returnNF_Tc EmptyBinds
-
-applyTcSubstToBinds (ThenBinds binds1 binds2)
- = applyTcSubstToBinds binds1 `thenNF_Tc` \ new_binds1 ->
- applyTcSubstToBinds binds2 `thenNF_Tc` \ new_binds2 ->
- returnNF_Tc (ThenBinds new_binds1 new_binds2)
-
-applyTcSubstToBinds (SingleBind bind)
- = substBind bind `thenNF_Tc` \ new_bind ->
- returnNF_Tc (SingleBind new_bind)
-
-applyTcSubstToBinds (AbsBinds tyvars dicts locprs dict_binds val_bind)
- = subst_tyvars tyvars `thenNF_Tc` \ new_tyvars ->
- mapNF_Tc applyTcSubstToId dicts `thenNF_Tc` \ new_dicts ->
- mapNF_Tc subst_pair locprs `thenNF_Tc` \ new_locprs ->
- mapNF_Tc subst_bind dict_binds `thenNF_Tc` \ new_dict_binds ->
- substBind val_bind `thenNF_Tc` \ new_val_bind ->
- returnNF_Tc (AbsBinds new_tyvars new_dicts new_locprs new_dict_binds new_val_bind)
- where
- subst_pair (l, g)
- = applyTcSubstToId l `thenNF_Tc` \ new_l ->
- applyTcSubstToId g `thenNF_Tc` \ new_g ->
- returnNF_Tc (new_l, new_g)
-
- subst_bind (v, e)
- = applyTcSubstToInst v `thenNF_Tc` \ new_v ->
- substExpr e `thenNF_Tc` \ new_e ->
- returnNF_Tc (new_v, new_e)
-\end{code}
-
-\begin{code}
--------------------------------------------------------------------------
-substBind :: TypecheckedBind -> NF_TcM TypecheckedBind
-
-substBind (NonRecBind mbinds)
- = applyTcSubstToMonoBinds mbinds `thenNF_Tc` \ new_mbinds ->
- returnNF_Tc (NonRecBind new_mbinds)
-
-substBind (RecBind mbinds)
- = applyTcSubstToMonoBinds mbinds `thenNF_Tc` \ new_mbinds ->
- returnNF_Tc (RecBind new_mbinds)
-
-substBind other = returnNF_Tc other
-
--------------------------------------------------------------------------
-applyTcSubstToMonoBinds :: TypecheckedMonoBinds -> NF_TcM TypecheckedMonoBinds
-
-applyTcSubstToMonoBinds EmptyMonoBinds = returnNF_Tc EmptyMonoBinds
-
-applyTcSubstToMonoBinds (AndMonoBinds mbinds1 mbinds2)
- = applyTcSubstToMonoBinds mbinds1 `thenNF_Tc` \ new_mbinds1 ->
- applyTcSubstToMonoBinds mbinds2 `thenNF_Tc` \ new_mbinds2 ->
- returnNF_Tc (AndMonoBinds new_mbinds1 new_mbinds2)
-
-applyTcSubstToMonoBinds (PatMonoBind pat grhss_w_binds locn)
- = substPat pat `thenNF_Tc` \ new_pat ->
- substGRHSsAndBinds grhss_w_binds `thenNF_Tc` \ new_grhss_w_binds ->
- returnNF_Tc (PatMonoBind new_pat new_grhss_w_binds locn)
-
-applyTcSubstToMonoBinds (VarMonoBind var expr)
- = applyTcSubstToId var `thenNF_Tc` \ new_var ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (VarMonoBind new_var new_expr)
-
-applyTcSubstToMonoBinds (FunMonoBind name ms locn)
- = applyTcSubstToId name `thenNF_Tc` \ new_name ->
- mapNF_Tc substMatch ms `thenNF_Tc` \ new_ms ->
- returnNF_Tc (FunMonoBind new_name new_ms locn)
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[BackSubst-Match-GRHSs]{Match and GRHSsAndBinds}
-%* *
-%************************************************************************
-
-\begin{code}
-substMatch :: TypecheckedMatch -> NF_TcM TypecheckedMatch
-
-substMatch (PatMatch pat match)
- = substPat pat `thenNF_Tc` \ new_pat ->
- substMatch match `thenNF_Tc` \ new_match ->
- returnNF_Tc (PatMatch new_pat new_match)
-
-substMatch (GRHSMatch grhss_w_binds)
- = substGRHSsAndBinds grhss_w_binds `thenNF_Tc` \ new_grhss_w_binds ->
- returnNF_Tc (GRHSMatch new_grhss_w_binds)
-
--------------------------------------------------------------------------
-substGRHSsAndBinds :: TypecheckedGRHSsAndBinds
- -> NF_TcM TypecheckedGRHSsAndBinds
-
-substGRHSsAndBinds (GRHSsAndBindsOut grhss binds ty)
- = mapNF_Tc subst_grhs grhss `thenNF_Tc` \ new_grhss ->
- applyTcSubstToBinds binds `thenNF_Tc` \ new_binds ->
- applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (GRHSsAndBindsOut new_grhss new_binds new_ty)
- where
- subst_grhs (GRHS guard expr locn)
- = substExpr guard `thenNF_Tc` \ new_guard ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (GRHS new_guard new_expr locn)
-
- subst_grhs (OtherwiseGRHS expr locn)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (OtherwiseGRHS new_expr locn)
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[BackSubst-Expr]{Running a substitution over a TypeCheckedExpr}
-%* *
-%************************************************************************
-
-ToDo: panic on things that can't be in @TypecheckedExpr@.
-
-\begin{code}
-substExpr :: TypecheckedExpr -> NF_TcM TypecheckedExpr
-
-substExpr (Var name)
- = applyTcSubstToId name `thenNF_Tc` \ new_name ->
- returnNF_Tc (Var new_name)
-
-substExpr (Lit (LitLitLit s ty))
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (Lit (LitLitLit s new_ty))
-
-substExpr other_lit@(Lit lit) = returnNF_Tc other_lit
-
-substExpr (Lam match)
- = substMatch match `thenNF_Tc` \ new_match ->
- returnNF_Tc (Lam new_match)
-
-substExpr (App e1 e2)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- returnNF_Tc (App new_e1 new_e2)
-
-substExpr (OpApp e1 op e2)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr op `thenNF_Tc` \ new_op ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- returnNF_Tc (OpApp new_e1 new_op new_e2)
-
-substExpr (SectionL expr op)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- substExpr op `thenNF_Tc` \ new_op ->
- returnNF_Tc (SectionL new_expr new_op)
-
-substExpr (SectionR op expr)
- = substExpr op `thenNF_Tc` \ new_op ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (SectionR new_op new_expr)
-
-substExpr (CCall fun args may_gc is_casm result_ty)
- = mapNF_Tc substExpr args `thenNF_Tc` \ new_args ->
- applyTcSubstToTy result_ty `thenNF_Tc` \ new_result_ty ->
- returnNF_Tc (CCall fun new_args may_gc is_casm new_result_ty)
-
-substExpr (SCC label expr)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (SCC label new_expr)
-
-substExpr (Case expr ms)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- mapNF_Tc substMatch ms `thenNF_Tc` \ new_ms ->
- returnNF_Tc (Case new_expr new_ms)
-
-substExpr (ListComp expr quals)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- substQuals quals `thenNF_Tc` \ new_quals ->
- returnNF_Tc (ListComp new_expr new_quals)
-
-substExpr (Let binds expr)
- = applyTcSubstToBinds binds `thenNF_Tc` \ new_binds ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (Let new_binds new_expr)
-
---ExplicitList: not in typechecked exprs
-
-substExpr (ExplicitListOut ty exprs)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- mapNF_Tc substExpr exprs `thenNF_Tc` \ new_exprs ->
- returnNF_Tc (ExplicitListOut new_ty new_exprs)
-
-substExpr (ExplicitTuple exprs)
- = mapNF_Tc substExpr exprs `thenNF_Tc` \ new_exprs ->
- returnNF_Tc (ExplicitTuple new_exprs)
-
-substExpr (If e1 e2 e3)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- substExpr e3 `thenNF_Tc` \ new_e3 ->
- returnNF_Tc (If new_e1 new_e2 new_e3)
-
-substExpr (ArithSeqOut expr info)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- substArithSeq info `thenNF_Tc` \ new_info ->
- returnNF_Tc (ArithSeqOut new_expr new_info)
-
-substExpr (TyLam tyvars expr)
- = subst_tyvars tyvars `thenNF_Tc` \ new_tyvars ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (TyLam new_tyvars new_expr)
-
-substExpr (TyApp expr tys)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- mapNF_Tc (applyTcSubstToTy) tys `thenNF_Tc` \ new_tys ->
- returnNF_Tc (TyApp new_expr new_tys)
-
-substExpr (DictLam dicts expr)
- = mapNF_Tc applyTcSubstToId dicts `thenNF_Tc` \ new_dicts ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (DictLam new_dicts new_expr)
-
-substExpr (DictApp expr dicts)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- mapNF_Tc applyTcSubstToId dicts `thenNF_Tc` \ new_dicts ->
- returnNF_Tc (DictApp new_expr new_dicts)
-
-substExpr (ClassDictLam dicts methods expr)
- = mapNF_Tc applyTcSubstToId dicts `thenNF_Tc` \ new_dicts ->
- mapNF_Tc applyTcSubstToId methods `thenNF_Tc` \ new_methods ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (ClassDictLam new_dicts new_methods new_expr)
-
-substExpr (Dictionary dicts methods)
- = mapNF_Tc applyTcSubstToId dicts `thenNF_Tc` \ new_dicts ->
- mapNF_Tc applyTcSubstToId methods `thenNF_Tc` \ new_methods ->
- returnNF_Tc (Dictionary new_dicts new_methods)
-
-substExpr (SingleDict name)
- = applyTcSubstToId name `thenNF_Tc` \ new_name ->
- returnNF_Tc (SingleDict new_name)
-
-#ifdef DPH
-
-substExpr (ParallelZF expr quals)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- substParQuals quals `thenNF_Tc` \ new_quals ->
- returnNF_Tc (ParallelZF new_expr new_quals)
-
---substExpr (ExplicitPodIn exprs) :: not in typechecked
-
-substExpr (ExplicitPodOut ty exprs)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- mapNF_Tc substExpr exprs `thenNF_Tc` \ new_exprs ->
- returnNF_Tc (ExplicitPodOut new_ty new_exprs)
-
-substExpr (ExplicitProcessor exprs expr)
- = mapNF_Tc substExpr exprs `thenNF_Tc` \ new_exprs ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (ExplicitProcessor new_exprs new_expr)
-
-#endif {- Data Parallel Haskell -}
-
--------------------------------------------------------------------------
-substArithSeq :: TypecheckedArithSeqInfo -> NF_TcM TypecheckedArithSeqInfo
-
-substArithSeq (From e)
- = substExpr e `thenNF_Tc` \ new_e ->
- returnNF_Tc (From new_e)
-
-substArithSeq (FromThen e1 e2)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- returnNF_Tc (FromThen new_e1 new_e2)
-
-substArithSeq (FromTo e1 e2)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- returnNF_Tc (FromTo new_e1 new_e2)
-
-substArithSeq (FromThenTo e1 e2 e3)
- = substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- substExpr e3 `thenNF_Tc` \ new_e3 ->
- returnNF_Tc (FromThenTo new_e1 new_e2 new_e3)
-
--------------------------------------------------------------------------
-substQuals :: [TypecheckedQual] -> NF_TcM [TypecheckedQual]
-
-substQuals quals
- = mapNF_Tc subst_qual quals
- where
- subst_qual (GeneratorQual pat expr)
- = substPat pat `thenNF_Tc` \ new_pat ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (GeneratorQual new_pat new_expr)
-
- subst_qual (FilterQual expr)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (FilterQual new_expr)
-
--------------------------------------------------------------------------
-#ifdef DPH
-substParQuals :: TypecheckedParQuals -> NF_TcM TypecheckedParQuals
-
-substParQuals (AndParQuals quals1 quals2)
- = substParQuals quals1 `thenNF_Tc` \ new_quals1 ->
- substParQuals quals2 `thenNF_Tc` \ new_quals2 ->
- returnNF_Tc (AndParQuals new_quals1 new_quals2)
-
---substParQuals (DrawnGenIn pats pat expr) :: not in typechecked
-
-substParQuals (DrawnGenOut pats convs pat expr)
- = mapNF_Tc substPat pats `thenNF_Tc` \ new_pats ->
- mapNF_Tc substExpr convs `thenNF_Tc` \ new_convs ->
- substPat pat `thenNF_Tc` \ new_pat ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (DrawnGenOut new_pats new_convs new_pat new_expr)
-
-substParQuals (IndexGen pats pat expr)
- = mapNF_Tc substExpr pats `thenNF_Tc` \ new_pats ->
- substPat pat `thenNF_Tc` \ new_pat ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (IndexGen new_pats new_pat new_expr)
-
-substParQuals (ParFilter expr)
- = substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (ParFilter new_expr)
-#endif {- Data Parallel Haskell -}
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[BackSubst-Pats]{Patterns}
-%* *
-%************************************************************************
-
-\begin{code}
-substPat :: TypecheckedPat -> NF_TcM TypecheckedPat
-
-substPat (WildPat ty)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (WildPat new_ty)
-
-substPat (VarPat v)
- = applyTcSubstToId v `thenNF_Tc` \ new_v ->
- returnNF_Tc (VarPat new_v)
-
-substPat (LazyPat pat)
- = substPat pat `thenNF_Tc` \ new_pat ->
- returnNF_Tc (LazyPat new_pat)
-
-substPat (AsPat n pat)
- = applyTcSubstToId n `thenNF_Tc` \ new_n ->
- substPat pat `thenNF_Tc` \ new_pat ->
- returnNF_Tc (AsPat new_n new_pat)
-
-substPat (ConPat n ty pats)
- = applyTcSubstToId n `thenNF_Tc` \ new_n ->
- -- ToDo: "n"'s global, so omit?
- applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- mapNF_Tc substPat pats `thenNF_Tc` \ new_pats ->
- returnNF_Tc (ConPat new_n new_ty new_pats)
-
-substPat (ConOpPat pat1 op pat2 ty)
- = substPat pat1 `thenNF_Tc` \ new_pat1 ->
- applyTcSubstToId op `thenNF_Tc` \ new_op ->
- substPat pat2 `thenNF_Tc` \ new_pat2 ->
- applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (ConOpPat new_pat1 new_op new_pat2 new_ty)
-
-substPat (ListPat ty pats)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- mapNF_Tc substPat pats `thenNF_Tc` \ new_pats ->
- returnNF_Tc (ListPat new_ty new_pats)
-
-substPat (TuplePat pats)
- = mapNF_Tc substPat pats `thenNF_Tc` \ new_pats ->
- returnNF_Tc (TuplePat new_pats)
-
-substPat (LitPat lit ty)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- returnNF_Tc (LitPat lit new_ty)
-
-substPat (NPat lit ty expr)
- = applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- substExpr expr `thenNF_Tc` \ new_expr ->
- returnNF_Tc (NPat lit new_ty new_expr)
-
-substPat (NPlusKPat n k ty e1 e2 e3)
- = applyTcSubstToId n `thenNF_Tc` \ new_n ->
- applyTcSubstToTy ty `thenNF_Tc` \ new_ty ->
- substExpr e1 `thenNF_Tc` \ new_e1 ->
- substExpr e2 `thenNF_Tc` \ new_e2 ->
- substExpr e3 `thenNF_Tc` \ new_e3 ->
- returnNF_Tc (NPlusKPat new_n k new_ty new_e1 new_e2 new_e3)
-
-#ifdef DPH
-substPat (ProcessorPat pats convs pat)
- = mapNF_Tc substPat pats `thenNF_Tc` \ new_pats ->
- mapNF_Tc substExpr convs `thenNF_Tc` \ new_convs ->
- substPat pat `thenNF_Tc` \ new_pat ->
- returnNF_Tc (ProcessorPat new_pats new_convs new_pat)
-#endif {- Data Parallel Haskell -}
-\end{code}
-
-%************************************************************************
-%* *
-\subsection[BackSubst-TyVar]{Running a substitution over type variables}
-%* *
-%************************************************************************
-
-The type variables in an @AbsBinds@ or @TyLam@ may have a binding in the
-substitution as a result of a @matchTy@ call. So we should subsitute for
-them too. The result should certainly be a type variable.
-
-\begin{code}
-subst_tyvars tyvars
- = mapNF_Tc applyTcSubstToTyVar tyvars `thenNF_Tc` \ new_tyvar_tys ->
- returnNF_Tc (map (getTyVar "subst_tyvars") new_tyvar_tys)
-\end{code}