The Haskell Prelude is a box of tools from 1998 which help you shoot yourself in the foot repeatedly.
While I agree the Prelude is not optimal, I’m curious as both a recent learner of Haskell what a better solution would be for newcomers to Haskell? Classy Prelude?
Consider the default Prelude a learners Prelude? Can we not change it now that ghc is slightly not caring about Haskell 98 full compatibility? I vote for fix the warts in the default Prelude.
Most people don’t disagree about changes to the Prelude, it would just take someone with amazing resolve and deep knowledge of GHC to figure out a migration plan and navigate the politics of this change. The academic side of the community isn’t going to champion this because there’s no papers in engineering work, and the industrial side of the community isn’t going to champion this because it’s more cost-effective to route around the problem by masking the broken bits.
And so we end up in the broken state we’re in through no fault of anyone, just a matter of incentive structure not being in place.
This is a fairly common first error. I think it’s nearly universal. Lazy I/O isn’t intuitive and, as the OP noted, people tend to use other tools for serious IO: Text and ByteString types (lazy and strict) instead of (lazy) [Char] and libraries like pipes and conduit.
The issue with strings in particular is that we often think of a string as being a single object, whereas Haskell’s default string is very much a collection (and a lazy, thunked, one).
Of course deepseq is an option as well, but it’s probably better to use a more appropriate collection type for most purposes.