
I think it would help to separate issues. If it were not for rebindable syntax, there would be no need for these "op" fields in (say) BindStmt etc. Instead, we'd have a fixed typing rule for BindStmt, and the desugarer would use the fixed Control.Monad.(>>=). The rebindable syntax thing just allows you to use a different (>>=), and therefore we must record the one we use in the BindStmt node. It's the same for ExprStmt. I believe you want to support rebindable syntax for monad comprehensions, so you have to record the rebindable (>>) and guard operators. But I don't think you intend to allow the programmer rebind composition (.), do you? If not, don't record it. The desugarer can use the fixed one from the Prelude. | Is this a valid approach? Should I move the "(>>) . guard" function | somewhere else? I had a look at the renamer where "(>>)" is added to the | statement "ExprStmt" the first time, but apparently you cannot call | "tcSyntaxOp" in the typechecker on this function if you construct it | with "HsApp (compose_op `HsApp` then_op) guard_op". Is there another | function which could typecheck such a constructed expression without | telling the user what functions we've used? I think it'd be easier just to record 'guard' and 'then' separately. Simon