The problem with Haskell is that while it is very effective at expressing ideas and logic, it is just as ineffective at expressing runtime behavior. In world where everything is lazily evaluated by default and garbage collected, it is very difficult to reason about how the code will actually execute. Are you trashing the cache? Fragmenting your heap? Are you misusing the instruction cache? For performance reasons, Haskell programmers often need to forcibly make operations strict and turn off the thunk essentially. This is a layer of complexity you don't often see in blogposts and Haskell tutorials. In contrast, I can look at C or C++ code and tell you more or less exactly how it will map to assembly (with some exceptions like when compilers decide to inline).
So in short, that Haskell you know is not the full story. I've written some Haskell programs and tried very, very hard to make them fast (they were parallelized too). At the end of the day, it's hard for a language to completely outclass another one because there are tradeoffs and life isn't so simple.