I shouldn't have deleted that comment, but I didn't want to bug you, as I did some digging and refreshed myself on the meaning of 'effect' as you were using it. What I was doing in my head was equating effect == side-effect, which is of course not always true.

I am not a hadkeller, but I don't believe the state monad has anything to do with mutable state. From my experience with scala, the state monad is simply a way to chain pure functions neatly together to make it seem as if there was mutable state. You still have referential transparency.

As long as the state is purely local, there is no diffence between making it seem like one has mutable state and having mutable state. The Kleisli category of State s is not referentially transparent for a nontrivial s in the sense that it is not cartesian (even modulo partiality).

State s only has one mutable field, and it's not part of a data structure, so one can't pass around references to that.

The functions returning State s a are still technically referentially transparent, but they don't act that way under do-notation (because x >> return () isn't necessarily equivalent to return ()).

Categories themselves are rarely nice for mathematics, but when they have pairs/tuples, they are called cartesian. Technically, this is only true when some equivalences hold, and those equivalences don't hold when the categories contain impure morphisms. The Kleisli category for a monad m over C has the objects of C and the C-morphisms of the structure a -> m b where a is the domain and b is the codomain. Even if C is pure (i. e. cartesian), the Kleisli category for m rarely is. One can argue that this means that the Kleisli category for m isn't referentially transparent.

Yes, it's unfortunate that the "biggest" monad in Haskell (IO) is also the most confusingly pointless in an imperative language. It confuses me to no end when people try to explain monads by starting with IO, as if it was more fundamental than nullables or lists!

Yes, but from an effect system PoV, IO is the starting point. Some of the most naive effect systems partition everything up into "pure" and "impure", so it seems to me that IO is a very intuitive starting point when discussing effect systems.

Some things that model side effects (e.g. the State monad) / track side effects (e.g. IO or ST) happen to have a convenient monadic interface.

However, there are plenty of pure things that also have convenient monadic interfaces. For example, Maybe/Option has a much more convenient interface than nulls do (since you can push common boiler plate into the standard library). Also, consider the List monad in haskell - [(x,y) | x < xs, y <- ys] desugars to xs >>= \x -> ys >>= \y -> return (x,y). Nothing to do with imperativeness or side effects, everything to do with iterating over two lists and generating all possible pairs.

Interesting. Due to my lack of depth on the subject, I was only referring to the use case of monads that I was aware of (encapsulating side effects.) Didn't know they had more general applicability in pure domains. Thanks for the heads up!

I'm not fluent in Haskell's syntax, but did your example of the List monad generate the cartesian product of both lists?