I/O changes
the world rather than being part of a computation per se. Naturally, there are many
times when what you want to do is change the world in some manner (if not, you
cannot even know a program has run). Haskell circumscribes all such side effects within
a very narrow "box" called Monadic IO. Nothing in a monad can get out, and nothing
outside a monad can get in.
Often, structured imperative programming approaches functional programming’s goals
of circumscribing I/O. Good design might require that input and output only happens in
a limited set of appropriately named functions. Less structured programming tends to
read and write to STDIO, files, graphic devices, etc., all over the place and in a way that
is difficult to predict. Functional programming takes the circumscription to a much
higher level.