only 20x? What happens when you reevaluate it with the python code not having any pieces that are C under the covers? (my understanding that a lot of python idioms for fast code basically turn into ah "use the approach that pushes as much work into C as possible")
Not in the same way at all.
Bytestring or hmatrix may have their primops in C, but the control flow stuff code for libs like Repa or Vector are pure Haskell (and in fact current state of the art work on Repa has it matching if not beating C code).
The crucial difference is that in python, these faster python idioms are for using C as the control code