I think saying "packages" was an error on my part, because how this is different from the usual C++/other language example is that Haskell is a ML language, and gives you a
lot of abstractions (rather than packages per say) to use. Generally using packages in haskell is easy because you don't care what abstraction they were written in (almost always IO is there somewhere, or they offer a doTheThingIO function which is the lowest common denominator), and if they're completely functional libraries then it
really really doesn't matter.
The commenter was railing against the abstractions the codebases used, not the underlying packages actually. I don't want to get into explaining it, but it is very easy to write production-ready simple haskell, but also very easy to spend hours building abstractions in the type system (normally) to build yourself a straight jacket. OK so if I explain it a little bit, there are at least three ways that have surfaced in recent time (lets say the last 5 years) on ways to structure large effectful haskell codebases (which is most software you'd want to write).
- Everything in IO (just do everything in the IO monad)
- monad stacks & transformers
- The ReaderT pattern
- Effects (free/freer, polysemy, fused-effects, etc)
All of these approaches have high quality libraries to support their use, but you could stay at that first one (everything in simple IO) and be very happy for a very long time.
I'd argue that C++'s problematic features are of a different nature -- when one of them goes wrong you normally have a much more disastrous outcome (whether at runtime or when you're trying to grok the code). For example compare C++'s templating system to haskell's support of generics for example, one is infinitely safer to approach and easier to understand than the other for the simple case, due to how the languages are built (i.e. no inheritance). Haskell it's more up to you to strangle yourself with the complexity -- the necessary abstractions are pretty simple (typeclasses, monads are simple in use, if not in concept), but the unnecessary abstractions basically scale to PhD.
I will absolutely concede that Haskell does encourage you to reach for higher and higher levels of abstraction for diminishing returns. But I will take Haskell's abstractions over Java's abstractions any day of the week, even though Haskell's can be more inscrutable.