Monads is a nice way to hide state I have to admit, but not because of referential transparency and "reasoning".
Monads is a nice way to hide state I have to admit, but not because of referential transparency and "reasoning".
Each Haskell monad might have a different implementation of the >>= (bind) operator, which is referentially transparent and which you can easily substitute. The IO monad would be an exception: I believe that one is not referentially transparent and thus cannot be substituted, because it's not implemented in Haskell. You can however imagine that it is a sort of state monad for the external world, but that's a fiction in practice.
(Note: Haskell monads are not "real monads" from category theory, and nor are monads in any other programming language AFAIK... So it's helpful to be very specific about what we're talking about when we use the word "monad" without context. You can implement a monad-like thing using classes in Python or many other languages, but those aren't referentially transparent and aren't typically the monads people are talking about in the context of pure functional programming.)