Working with monads and monad stacks
Monads are very useful abstractions, and like any sufficiently complex abstraction, many monads too incur some overhead. Two notable exceptions are IO and ST, which are eliminated during compilation. A single simple monad such as Reader or Writer has very minimal overhead, but monad stacks can incur unfortunate slowdowns. In most cases, the convenient nature of programming in a monad stack far outweighs the small overhead, because cost centers are rarely located in monad operations (excluding IO and ST).
If you have an expensive subroutine in a State monad, it might be possible to convert it to ST for a big speedup. However,
State is more expressive than ST so conversion is not always feasible.