Effect separation
Like ordinary types give you a way to distinguish data, monads give you a way to distinguish effects.
Elixir
Here is an example in Elixir, which is a nearly-pure functional language on top of Erlang. This example is derived from a real-world situation that occurs very often at my work.
def handle_call(:get_config_foo, _, state) do:
  {:reply, state.foo, state}
end
def handle_call(:get_bar, _, state) do:
  {:reply, state.bar, state}
end
def handle_call({:set_bar, bar}, _, state) do:
  {:reply, :ok, %{state | bar: bar}}
end
This defines an API of a GenServer, which is a little Erlang node that holds some state and allows you to query it as well as change it. The first call, :get_config_foo reads an immutable config setting. The second set of calls, :get_bar and {:set_bar, bar}, gets and sets a mutable state variable.
How I wish I had monads here, to prevent the following bug:
def handle_call({:set_bar, bar}, _, state) do:
  {:reply, :ok, %{state | foo: bar}}
end
Can you spot the mistake? Well, I just wrote a readonly value. Nothing in Elixir prevents this. You can't mark some parts of your GenServer state as readonly, and others als read-write.
Haskell: Reader and State
In Haskell you can use different monads to specify different kinds of effects. Here are readonly state (Reader) and read-write state:
data Reader r a = Reader (r -> a)
data State s a = State (s -> (a, s))
Reader allows you to access the config state r to return some value a. State allows you to read the state, return some value and to modify the state. Both are monads, which essentially means that you can chain those state accesses sequentially in an imperative fashion. In Reader you can first read one config setting, and then (based on that first setting), read another setting. In State, you can read the state, and then (based on what you read) modify it in a further way. But you can never modify the state in Reader while you execute it.
Deterministic effects
Let me repeat this. Binding several calls to Reader assures you that you can never modify the reader state inbetween. If you have getConfigFoo1 :: Reader Config Foo1 and getConfigFoo2 :: Foo1 -> Reader Config Foo2 and you do getAllConfig = getConfigFoo1 >>= getConfigFoo2, then you have certainty that both queries will run on the same Config. Elixir does not have this feature and allows the above mentioned bug go unnoticed.
Other effects where this is useful is Writer (write-only state, e.g. logging) and Either (exception handling). When you have Writer instead of Reader or State, you can be sure that your state is ever only appended to. When you have Either, you know exactly the type of exceptions that can occur. This is all much better than using IO for logging and exception handling.