
<much snipping>
Also, note, if you use the operators in Control.Applicative, then:
return $ foo $(bar1) $(bar2) $(bar3) ...
can be:
return foo <*> bar1 <*> bar2 <*> bar3 ...
or:
foo <$> bar1 <*> bar2 <*> bar3
I don't (personally) see how that's any more cryptic than placing brackets around around the monadic values themselves. ...
Seconded. The main difference with brackes is that the application to pure values looks the same as normal application.
To get outside the scope of idiom brackets/applicative, you'd need a use case like:
if $(mexpr) then branch1 else branch2
or (lest that be to easy):
case $(mexpr) of p1 -> branch1 p2 -> branch2 ...
In other words, something where you're not simply applying a pure function to a bunch of monadic arguments. I can't say I've run into such patterns much myself, but I've been told they're common in xmonad, and may be elsewhere.
General purpose brackets are overkill here. I would really like a simple monadic case. What's so bad about caseM mexpr of p1 -> branch1 p2 -> branch2 vvvv (mexpr >>= \e -> case e of p1 -> branch1 p2 -> branch2) It's simple sugar for working with monadic code, much like do notation. (indeed, it seems to plug a gap - we have do for sequencing, liftM and so on for application, but no sugar for case discrimination) It's a much simpler sort of thing than this fancy sugar for intermixing code in various monads people have been talking about (so far it seems assumed that one is just Identity...) Brandon