
On 5 September 2011 02:38, Sebastian Fischer
These are important questions. I think there is a trade-off between supporting many cases and having a simple desugaring. We should find a sweet-spot where the desugaring is reasonably simple and covers most idiomatic cases.
I have proposed a desugaring (in executable form) at https://gist.github.com/1194308. My desugaring aims for a slightly different design that does not try to detect "return" and instead treats the use of <*, *> and liftA2 purely as an optimisation - so any computation using "do" still generates a Monad constraint, but it may be desugared in a more efficient way than it is currently by using the Applicative combinators. (If you do want to support the type checker only generating requests for an Applicative constraint you could just insist that user code writes "pure" instead of "return", in which case this would be quite easy to implement) There are still some interesting cases in my proposal. For example, if you have my second example: x <- computation1 y <- computation2 z <- computation3 y computation4 x You might reasonably "reassociate" computation2 and computation3 together and desugar this to: liftA2 computation1 (computation2 >>= \y -> computation3 y) >>= \(x, _z) -> computation4 x But currently I desugar to: liftA2 computation1 computation2 >>= \(x, y) -> computation3 y *> computation4 x It wouldn't be too hard (and perhaps a nice exercise) to modify the desugaring to do this reassocation. Max