+ go loc (RecStmt { recS_stmts = rec_stmts, recS_later_ids = later_ids
+ , recS_rec_ids = rec_ids, recS_ret_fn = return_op
+ , recS_mfix_fn = mfix_op, recS_bind_fn = bind_op
+ , recS_rec_rets = rec_rets, recS_dicts = binds }) stmts
+ = ASSERT( length rec_ids > 0 )
+ goL (new_bind_stmt : let_stmt : stmts)
+ where
+ -- returnE <- dsExpr return_id
+ -- mfixE <- dsExpr mfix_id
+ new_bind_stmt = L loc $ BindStmt (mkLHsPatTup later_pats) mfix_app
+ bind_op
+ noSyntaxExpr -- Tuple cannot fail
+
+ let_stmt = L loc $ LetStmt (HsValBinds (ValBindsOut [(Recursive, binds)] []))
+
+ tup_ids = rec_ids ++ filterOut (`elem` rec_ids) later_ids
+ rec_tup_pats = map nlVarPat tup_ids
+ later_pats = rec_tup_pats
+ rets = map noLoc rec_rets
+
+ mfix_app = nlHsApp (noLoc mfix_op) mfix_arg
+ mfix_arg = noLoc $ HsLam (MatchGroup [mkSimpleMatch [mfix_pat] body]
+ (mkFunTy tup_ty body_ty))
+ mfix_pat = noLoc $ LazyPat $ mkLHsPatTup rec_tup_pats
+ body = noLoc $ HsDo DoExpr rec_stmts return_app body_ty
+ return_app = nlHsApp (noLoc return_op) (mkLHsTupleExpr rets)
+ body_ty = mkAppTy m_ty tup_ty
+ tup_ty = mkBoxedTupleTy (map idType tup_ids) -- Deals with singleton case
+