X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=compiler%2FhsSyn%2FHsExpr.lhs;h=f638f657bced5eeb3caeb040e81de97fd795472a;hb=855d87925b0049d23e536c12b9af8e1b545e28f0;hp=cdf7322b46d83055ebcb86a7c51e71620efcf10e;hpb=a9db145ff5b02ad9c79fcef44898a37254cc6c1a;p=ghc-hetmet.git diff --git a/compiler/hsSyn/HsExpr.lhs b/compiler/hsSyn/HsExpr.lhs index cdf7322..f638f65 100644 --- a/compiler/hsSyn/HsExpr.lhs +++ b/compiler/hsSyn/HsExpr.lhs @@ -777,8 +777,8 @@ pprGRHSs :: (OutputableBndr idL, OutputableBndr idR) => HsMatchContext idL -> GRHSs idR -> SDoc pprGRHSs ctxt (GRHSs grhss binds) = vcat (map (pprGRHS ctxt . unLoc) grhss) - $$ if isEmptyLocalBinds binds then empty - else text "where" $$ nest 4 (pprBinds binds) + $$ ppUnless (isEmptyLocalBinds binds) + (text "where" $$ nest 4 (pprBinds binds)) pprGRHS :: (OutputableBndr idL, OutputableBndr idR) => HsMatchContext idL -> GRHS idR -> SDoc @@ -847,26 +847,38 @@ data StmtLR idL idR -- the names which they group over in statements -- Recursive statement (see Note [RecStmt] below) - | RecStmt [LStmtLR idL idR] - --- The next two fields are only valid after renaming - [idR] -- The ids are a subset of the variables bound by the - -- stmts that are used in stmts that follow the RecStmt - - [idR] -- Ditto, but these variables are the "recursive" ones, - -- that are used before they are bound in the stmts of - -- the RecStmt. From a type-checking point of view, - -- these ones have to be monomorphic - - --- These fields are only valid after typechecking - [PostTcExpr] -- These expressions correspond 1-to-1 with - -- the "recursive" [id], and are the - -- expressions that should be returned by - -- the recursion. - -- They may not quite be the Ids themselves, - -- because the Id may be *polymorphic*, but - -- the returned thing has to be *monomorphic*. - (DictBinds idR) -- Method bindings of Ids bound by the - -- RecStmt, and used afterwards + | RecStmt + { recS_stmts :: [LStmtLR idL idR] + + -- The next two fields are only valid after renaming + , recS_later_ids :: [idR] -- The ids are a subset of the variables bound by the + -- stmts that are used in stmts that follow the RecStmt + + , recS_rec_ids :: [idR] -- Ditto, but these variables are the "recursive" ones, + -- that are used before they are bound in the stmts of + -- the RecStmt. + -- An Id can be in both groups + -- Both sets of Ids are (now) treated monomorphically + -- See Note [How RecStmt works] for why they are separate + + -- Rebindable syntax + , recS_bind_fn :: SyntaxExpr idR -- The bind function + , recS_ret_fn :: SyntaxExpr idR -- The return function + , recS_mfix_fn :: SyntaxExpr idR -- The mfix function + + -- These fields are only valid after typechecking + , recS_rec_rets :: [PostTcExpr] -- These expressions correspond 1-to-1 with + -- recS_rec_ids, and are the + -- expressions that should be returned by + -- the recursion. + -- They may not quite be the Ids themselves, + -- because the Id may be *polymorphic*, but + -- the returned thing has to be *monomorphic*, + -- so they may be type applications + + , recS_dicts :: DictBinds idR -- Method bindings of Ids bound by the + -- RecStmt, and used afterwards + } \end{code} ExprStmts are a bit tricky, because what they mean @@ -894,28 +906,44 @@ depends on the context. Consider the following contexts: Array comprehensions are handled like list comprehensions -=chak -Note [RecStmt] -~~~~~~~~~~~~~~ +Note [How RecStmt works] +~~~~~~~~~~~~~~~~~~~~~~~~ Example: - HsDo [ BindStmt x ex + HsDo [ BindStmt x ex - , RecStmt [a::forall a. a -> a, b] - [a::Int -> Int, c] - [ BindStmt b (return x) - , LetStmt a = ea - , BindStmt c ec ] + , RecStmt { recS_rec_ids = [a, c] + , recS_stmts = [ BindStmt b (return (a,c)) + , LetStmt a = ...b... + , BindStmt c ec ] + , recS_later_ids = [a, b] - , return (a b) ] + , return (a b) ] Here, the RecStmt binds a,b,c; but - Only a,b are used in the stmts *following* the RecStmt, - This 'a' is *polymorphic' - Only a,c are used in the stmts *inside* the RecStmt *before* their bindings - This 'a' is monomorphic -Nota Bene: the two a's have different types, even though they -have the same Name. +Why do we need *both* rec_ids and later_ids? For monads they could be +combined into a single set of variables, but not for arrows. That +follows from the types of the respective feedback operators: + + mfix :: MonadFix m => (a -> m a) -> m a + loop :: ArrowLoop a => a (b,d) (c,d) -> a b c + +* For mfix, the 'a' covers the union of the later_ids and the rec_ids +* For 'loop', 'c' is the later_ids and 'd' is the rec_ids + +Note [Typing a RecStmt] +~~~~~~~~~~~~~~~~~~~~~~~ +A (RecStmt stmts) types as if you had written + + (v1,..,vn, _, ..., _) <- mfix (\~(_, ..., _, r1, ..., rm) -> + do { stmts + ; return (v1,..vn, r1, ..., rm) }) + +where v1..vn are the later_ids + r1..rm are the rec_ids \begin{code} @@ -934,7 +962,11 @@ pprStmt (TransformStmt (stmts, _) usingExpr maybeByExpr) byExprDoc = maybe empty (\byExpr -> hsep [ptext (sLit "by"), ppr byExpr]) maybeByExpr pprStmt (GroupStmt (stmts, _) groupByClause) = (hsep [stmtsDoc, ptext (sLit "then group"), pprGroupByClause groupByClause]) where stmtsDoc = interpp'SP stmts -pprStmt (RecStmt segment _ _ _ _) = ptext (sLit "rec") <+> braces (vcat (map ppr segment)) +pprStmt (RecStmt { recS_stmts = segment, recS_rec_ids = rec_ids, recS_later_ids = later_ids }) + = ptext (sLit "rec") <+> + vcat [ braces (vcat (map ppr segment)) + , ifPprDebug (vcat [ ptext (sLit "rec_ids=") <> ppr rec_ids + , ptext (sLit "later_ids=") <> ppr later_ids])] pprGroupByClause :: (OutputableBndr id) => GroupByClause id -> SDoc pprGroupByClause (GroupByNothing usingExpr) = hsep [ptext (sLit "using"), ppr usingExpr]