Haskell can definitely take more than 1-2 months to pass the learning curve, especially without a good mentor.
You generally shouldn't need to "pull IO through half this module", since you can just lift the large pure part with "fmap" to operate on the inner IO. But using these combinators effectively does take some learning.
The approach to IO that Haskell uses is not "academic", it is extremely practical: By typing effects you get immense practical, not academic, benefits.
Pulling and pushing bytes outside the system is trivial.
Depends on what level of abstraction you want to be at. If you use C-style IO, that's fine, but low level. If you use lazy-IO, that unfortunately made it into the Prelude, forget your performance. The Right Way is to use enumerators / left-fold based IO, or the pipe or conduit packages. But that's not trivial, yet. (Though not insanely hard, either.)
So Haskell makes IO harder by making you learn which modules use lazy I/O and avoid them? I can agree with that. But I don't think that's what people generally try to say when they claim IO in Haskell is hard or bad. People think the IO/effect segregation in Haskell makes IO bad or hard, when it's in fact just the opposite.