Programs should be these beautiful mathematical models that describe things - stick something in, get something out. Stick the same thing each time and get the same thing out each time.
Unfortunately to be useful programs have to be allowed to deal with messy stuff that can have side effects or some other ugly situation, or read input from a user or other programs.
You use monads to be explicit about where your program is messy and where it is isn't messy.
That can be stuff like IO, or stuff like Maybe (I dunno if what I'm getting here will even have a result - if it does, then it'll be Just (the result) otherwise it'll be Nothing) but the point is there is some messiness in there and you want to know there is messiness, otherwise you dont know what parts of your programs have messiness in them.
Perhaps you can think of them as atomic actions in concurrent programming? You declare something as atomic because you want to know the stuff inside the atom at least won't be affected by the rest of the concurrent messiness, so you can think about the pieces inside it as a non-concurrent piece.