The documentation for Control.Monad.List.ListT states that it “does not yield a monad unless the argument monad is commutative.”
-
How do I find out whether a monad is commutative? Is there a CommutativeMonad typeclass? Should there be?
-
In particular, is Control.Monad.RWS.Lazy.RWS a commutative monad?
In general, a monad is commutative if the expression
a >>= \x -> b >>= \y -> f x yis equivalent tob >>= \y -> a >>= \x -> f x y.In other words, it is commutative if the order of side effects is not important. We can replace the expression:
with one which switches the arguments.
MostMany common monads are commutative, but you can determine if a particular monad is commutative by either looking at the design and logicking it, or by writing a small program to test it with appropriate expressions (which naturally depend on the nature of the monad). As far as I know there is no CommutativeMonad typeclass.