In my area of business - back office IT for a financial institution - it is very common for a software component to carry a global configuration around, to log its progress, to
I recently "fell" on monad composition in the context of F#. I wrote a DSL with a strong reliance on the state monad: All components rely on the state monad: the parser (parser monad based on state monad), variable matching tables (more than one for internal types), identifier look up tables. And as these components all work together, they rely on the same state monad. Therefore there is a notion of state composition that brings together the different local states, and the notion of state accessors that give each algo their own state visibility.
Initially, the design was really "just one big state monad". But then I started needing states with only local life times, and yet still in the context of the "persistent" state (and again, all these states are managed by state monads). For that I did need to introduce state monad transformers that augment the state and adapt the state monads together. I also added a transformer to move freely between a state monad and a continuation state monad but I have not bothered to use it.
Therefore, to answer the question: yes, monad transformers exist in the "wild". Yet I would argue strongly against using them "out of the box". Write your application with simple building blocks, using small hand crafted bridges between your modules, if you do end up using something like a monad transformer, that's great; Do not start from there.
And about the type signatures: I have come to think of this type of programming as something very similar to playing blindfold chess (and I am not a chess player): your skill level needs to be at the point that you "see" your functions and types fitting together. The type signatures mostly end up being a distraction, unless you explicitly want to add type constraints for safety reasons (or because the compiler forces you to give them such as with F# records).