+ (_, b_ty) = splitAppTy result_ty -- result_ty must be of the form (m b)
+
+ go [ReturnStmt expr]
+ = dsExpr expr `thenDs` \ expr2 ->
+ returnDs (mkApps (Var return_id) [Type b_ty, expr2])
+
+ go (GuardStmt expr locn : stmts)
+ = do_expr expr locn `thenDs` \ expr2 ->
+ go stmts `thenDs` \ rest ->
+ returnDs (mkIfThenElse expr2 rest (App (Var zero_id) (Type b_ty)))
+
+ go (ExprStmt expr locn : stmts)
+ = do_expr expr locn `thenDs` \ expr2 ->
+ let
+ (_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
+ in
+ if null stmts then
+ returnDs expr2
+ else
+ go stmts `thenDs` \ rest ->
+ newSysLocalDs a_ty `thenDs` \ ignored_result_id ->
+ returnDs (mkApps (Var then_id) [Type a_ty, Type b_ty, expr2,
+ Lam ignored_result_id rest])
+
+ go (LetStmt binds : stmts )
+ = go stmts `thenDs` \ rest ->
+ dsLet binds rest
+
+ go (BindStmt pat expr locn : stmts)
+ = putSrcLocDs locn $
+ dsExpr expr `thenDs` \ expr2 ->
+ let
+ (_, a_ty) = splitAppTy (coreExprType expr2) -- Must be of form (m a)
+ zero_expr = TyApp (HsVar zero_id) [b_ty]
+ main_match = PatMatch pat (SimpleMatch (
+ HsDoOut do_or_lc stmts return_id then_id zero_id result_ty locn))
+ the_matches
+ = if failureFreePat pat
+ then [main_match]
+ else [main_match, PatMatch (WildPat a_ty) (SimpleMatch zero_expr)]
+ in
+ matchWrapper DoBindMatch the_matches match_msg
+ `thenDs` \ (binders, matching_code) ->
+ returnDs (mkApps (Var then_id) [Type a_ty, Type b_ty, expr2,
+ mkLams binders matching_code])