- -- After renaming, the ids are the binders bound by the stmts and used
- -- after them
-
- | TransformStmt ([LStmt idL], [idR]) (LHsExpr idR) (Maybe (LHsExpr idR))
- -- After renaming, the IDs are the binders occurring within this
- -- transform statement that are used after it
- -- "qs, then f by e" ==> TransformStmt (qs, binders) f (Just e)
- -- "qs, then f" ==> TransformStmt (qs, binders) f Nothing
-
- | GroupStmt ([LStmt idL], [(idR, idR)]) (GroupByClause idR)
- -- After renaming, the IDs are the binders occurring within this
- -- transform statement that are used after it which are paired with
- -- the names which they group over in statements
-
- -- Recursive statement (see Note [RecStmt] below)
+ (SyntaxExpr idR) -- Polymorphic `mzip` for monad comprehensions
+ (SyntaxExpr idR) -- The `>>=` operator
+ (SyntaxExpr idR) -- Polymorphic `return` operator
+ -- with type (forall a. a -> m a)
+ -- See notes [Monad Comprehensions]
+ -- After renaming, the ids are the binders
+ -- bound by the stmts and used after them
+
+ -- "qs, then f by e" ==> TransformStmt qs binders f (Just e) (return) (>>=)
+ -- "qs, then f" ==> TransformStmt qs binders f Nothing (return) (>>=)
+ | TransformStmt
+ [LStmt idL] -- Stmts are the ones to the left of the 'then'
+
+ [idR] -- After renaming, the Ids are the binders occurring
+ -- within this transform statement that are used after it
+
+ (LHsExpr idR) -- "then f"
+
+ (Maybe (LHsExpr idR)) -- "by e" (optional)
+
+ (SyntaxExpr idR) -- The 'return' function for inner monad
+ -- comprehensions
+ (SyntaxExpr idR) -- The '(>>=)' operator.
+ -- See Note [Monad Comprehensions]
+
+ | GroupStmt {
+ grpS_stmts :: [LStmt idL], -- Stmts to the *left* of the 'group'
+ -- which generates the tuples to be grouped
+
+ grpS_bndrs :: [(idR, idR)], -- See Note [GroupStmt binder map]
+
+ grpS_by :: Maybe (LHsExpr idR), -- "by e" (optional)
+
+ grpS_using :: LHsExpr idR,
+ grpS_explicit :: Bool, -- True <=> explicit "using f"
+ -- False <=> implicit; grpS_using is filled in with
+ -- 'groupWith' (list comprehensions) or
+ -- 'groupM' (monad comprehensions)
+
+ -- Invariant: if grpS_explicit = False, then grp_by = Just e
+ -- That is, we can have group by e
+ -- group using f
+ -- group by e using f
+
+ grpS_ret :: SyntaxExpr idR, -- The 'return' function for inner monad
+ -- comprehensions
+ grpS_bind :: SyntaxExpr idR, -- The '(>>=)' operator
+ grpS_fmap :: SyntaxExpr idR -- The polymorphic 'fmap' function for desugaring
+ } -- See Note [Monad Comprehensions]
+
+ -- Recursive statement (see Note [How RecStmt works] below)