To push side effects to the edge you have to only use do notation and monads when you absolutely have no choice, which is not done in practice with haskell.
>The presence of monads does not necessarily mean side effects
The presence of a functor does not mean side effects. The presence of a monad implies composition and binding which does imply a side effect. Even maybe monads composed have side effects that can produce output that the function itself can never produce on it's own.
For example let's say I have a maybe monad that will never produce "Nothing."
b :: int -> Maybe Int
b x = Just x
but I can produce a side effect by binding it with Nothing. Nothing >>= b
The above yields "Nothing," even though it is not part of the definition of b. It is a contextual side effect passed on through monadic composition. Normal composition outside of monadic composition usually does not have this property.