TL DR
They are the same.
Some history lessons
State , Writer and Reader were inspired by Marx Jones Functional Programming with Overload and Higher Order Polymorphism , where he defined Reader as follows:
A Reader monad is used to allow a calculation to access stored values ββin some environment (represented by type r in the following definition).
> instance Monad (r->) where > result x = \r -> x > x `bind` f = \r -> f (xr) r
As a missing comment, it is interesting to note that these two functions are simply standard K and S combinatorial combinators.
He later defines (almost) today MonadReader :
Reader monads : a monad class for describing computations that are considered in some fixed environment:
> class Monad m => ReaderMonad mr where > env :: r -> ma -> ma > getenv :: mr > instance ReaderMonad (r->) r where > env ec = \_ -> ce > getenv = id
getenv just ask , and env is local . const local . const . Therefore, this definition already contained all the relevant parts of a Reader . Ultimately, Jones defines the ReaderT monad ReaderT ( BComp is the reverse composition):
To begin with, it is useful to define two different forms of composition; forward ( FComp ) and backward ( BComp ):
> data FComp mna = FC (n (ma)) > data BComp mna = BC (m (na))
[excluding instances of Functor, Monad and OutOf]
> type ReaderT r = BComp (r ->)
Since StateT , WriterT , and others have their own version without a transformer, it would be logical to have Reader r , which is actually the same as (->) r .
In any case, Reader , Writer and State are currently defined in terms of their version of the transformer, and you use their corresponding Monad* typeclass ( MonadReader ).
Conclusion
So are they interchangeable in all customs?
Yes.
And what is the real significance of the differences between the two Monads?
No, except that ReaderT is actually a monad transformer, which simplifies the work.