Just FYI, I ran into a draft paper which has example code using the following monad stack (in Racket, not Haskell): (ReaderT (FailT (NondetT (StateT+ (ReaderT (StateT+ ID)))))) And thought how awful that would be using mtl or transformers.
Is there a comparison between ether and monad-classes anywhere?
I'm not aware of such a comparison, but off the top of my head:
monad-classes use type families to dispatch, ether uses overlapping instances (they offer more extensibility, you can define your own handlers).
monad-classes dispatches based on the effect type, ether uses separate tags (which is strictly more general, you can recover monad-classes behavior in ether by using implicit tagging).