It’s not a language issue. In most sane languages you can write readable code. And most languages also give you enough freedom to write unreadable code.
Here are some reasons why advanced Haskell code might not be readable if you aren’t already experienced with this style of coding:
- uses the C preprocessor extensively (usually to workaround API changes in upstream libraries, but sometimes used for actual code generation, like in a particular streaming library)
- uses long TH declarations that give no insight into what they do (you only know they have to return a `Q [Dec]` but it’s not obvious what, and dumping splices only goes so far; it can even download things from the Internet to generate code!)
- uses advanced concepts like Church/Scott encodings of data types (though with some comments this really shouldn’t be hard)
- excessive type level meta programming
- uses concepts like Bazaar, Bizarre, Conjoined, Strong, Yoneda, etc
By the way for some laughs you can read about how to write to write a factorial program in Haskell from simple straightforward styles to convoluted ones that use many advanced techniques: https://www.cs.utexas.edu/~cannata/cs345/Class%20Notes/10%20... I hope no one actually writes production code like this but it does show you how much of a steep learning curve could be needed before you understand certain kinds of Haskell code.