+data Match id
+ = Match
+ [Pat id] -- The patterns
+ (Maybe (HsType id)) -- A type signature for the result of the match
+ -- Nothing after typechecking
+
+ (GRHSs id)
+
+-- GRHSs are used both for pattern bindings and for Matches
+data GRHSs id
+ = GRHSs [GRHS id] -- Guarded RHSs
+ (HsBinds id) -- The where clause
+ PostTcType -- Type of RHS (after type checking)
+
+data GRHS id
+ = GRHS [Stmt id] -- The RHS is the final ResultStmt
+ SrcLoc
+
+mkSimpleMatch :: [Pat id] -> HsExpr id -> Type -> SrcLoc -> Match id
+mkSimpleMatch pats rhs rhs_ty locn
+ = Match pats Nothing (GRHSs (unguardedRHS rhs locn) EmptyBinds rhs_ty)
+
+unguardedRHS :: HsExpr id -> SrcLoc -> [GRHS id]
+unguardedRHS rhs loc = [GRHS [ResultStmt rhs loc] loc]
+\end{code}
+
+@getMatchLoc@ takes a @Match@ and returns the
+source-location gotten from the GRHS inside.
+THis is something of a nuisance, but no more.
+
+\begin{code}
+getMatchLoc :: Match id -> SrcLoc
+getMatchLoc (Match _ _ (GRHSs (GRHS _ loc : _) _ _)) = loc
+\end{code}
+
+We know the list must have at least one @Match@ in it.
+
+\begin{code}
+pprMatches :: (OutputableBndr id) => HsMatchContext id -> [Match id] -> SDoc
+pprMatches ctxt matches = vcat (map (pprMatch ctxt) matches)
+
+-- Exported to HsBinds, which can't see the defn of HsMatchContext
+pprFunBind :: (OutputableBndr id) => id -> [Match id] -> SDoc
+pprFunBind fun matches = pprMatches (FunRhs fun) matches
+
+-- Exported to HsBinds, which can't see the defn of HsMatchContext
+pprPatBind :: (OutputableBndr id)
+ => Pat id -> GRHSs id -> SDoc
+pprPatBind pat grhss = sep [ppr pat, nest 4 (pprGRHSs PatBindRhs grhss)]
+
+
+pprMatch :: OutputableBndr id => HsMatchContext id -> Match id -> SDoc
+pprMatch ctxt (Match pats maybe_ty grhss)
+ = pp_name ctxt <+> sep [sep (map ppr pats),
+ ppr_maybe_ty,
+ nest 2 (pprGRHSs ctxt grhss)]
+ where
+ pp_name (FunRhs fun) = ppr fun -- Not pprBndr; the AbsBinds will
+ -- have printed the signature
+ pp_name LambdaExpr = char '\\'
+ pp_name other = empty
+
+ ppr_maybe_ty = case maybe_ty of
+ Just ty -> dcolon <+> ppr ty
+ Nothing -> empty
+
+
+pprGRHSs :: OutputableBndr id => HsMatchContext id -> GRHSs id -> SDoc
+pprGRHSs ctxt (GRHSs grhss binds ty)
+ = vcat (map (pprGRHS ctxt) grhss)
+ $$
+ (if nullBinds binds then empty
+ else text "where" $$ nest 4 (pprDeeper (ppr binds)))
+
+
+pprGRHS :: OutputableBndr id => HsMatchContext id -> GRHS id -> SDoc
+
+pprGRHS ctxt (GRHS [ResultStmt expr _] locn)
+ = pp_rhs ctxt expr
+
+pprGRHS ctxt (GRHS guarded locn)
+ = sep [char '|' <+> interpp'SP guards, pp_rhs ctxt expr]
+ where
+ ResultStmt expr _ = last guarded -- Last stmt should be a ResultStmt for guards
+ guards = init guarded
+
+pp_rhs ctxt rhs = matchSeparator ctxt <+> pprDeeper (ppr rhs)
+\end{code}
+
+
+
+%************************************************************************
+%* *
+\subsection{Do stmts and list comprehensions}
+%* *
+%************************************************************************
+
+\begin{code}
+data Stmt id
+ = BindStmt (Pat id) (HsExpr id) SrcLoc
+ | LetStmt (HsBinds id)
+ | ResultStmt (HsExpr id) SrcLoc -- See notes that follow
+ | ExprStmt (HsExpr id) PostTcType SrcLoc -- See notes that follow
+ -- The type is the *element type* of the expression
+
+ -- ParStmts only occur in a list comprehension
+ | ParStmt [[Stmt id]] -- List comp only: parallel set of quals
+ | ParStmtOut [([id], [Stmt id])] -- PLC after renaming; the ids are the binders
+ -- bound by the stmts
+
+ -- mdo-notation (only exists after renamer)
+ -- The ids are a subset of the variables bound by the stmts that
+ -- either (a) are used before they are bound in the stmts
+ -- or (b) are used in stmts that follow the RecStmt
+ | RecStmt [id]
+ [Stmt id]
+ [HsExpr id] -- Post type-checking only; these expressions correspond
+ -- 1-to-1 with the [id], and are the expresions 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.