I do not have experience commposing monads (maybe John Hughes can chime in?), but I'll address where Bernhard Reus writes:
This can be avoided by using type aliases but then the monads in use cannot be instances of the Monad class. But not declaring the monads to be in class Monad can hardly be good style, can it?
GHC's source code defines many monads not in class Monad. I'll write some untested code to give an idea of the naming conventions used: type FooMd out = (a,b,c)->((a,b,c),out) returnFooMd out = \s0->out thenFooMd p k = \s0->let (s,out) = p s0 in k out s method1FooMd ... = ... method2FooMd ... = ... the biggest disadvantage is that you cannot use the do notation but rather have to write, eg, method1FooMd x y `thenFooMd` (\result1-> method2FooMd z result1 `thenFooMd` (\result2-> ... of course, you also cannot use liftM and other library functions with (Monad m)=> in their signature, but I do not mind that so much as loss of the do notation. -- Richard Uhtenwoldt