Haskell Performance: Lowercase

I was trying to track down some issues with some text processing
programs that I was writing in Haskell, and ran into an interesting
problem. I made one small change and my program ended up being 5 times
slower, and I had to backtrack to try and find out what it was. So,
given a simple Haskell program that sees if a word is in a wordlist:

To search a smallish list of about 300K words takes 0.040 seconds on my
computer, compared to 0.200 seconds for Python and 0.210 seconds for a
naive Haskell implementation that is not using ByteStrings. However,
let’s just add lowercase to the equation:

Suddenly, the ByteString version becomes about 30% slower than the
naive version — 0.337 seconds vs. 0.251 seconds — and is even slower
than the Python version. What the heck is going on here? Trying an empty
map (i.e., C.map id x) resulted in something fast, so I’m suspecting
that the lowercase function itself is slow.

Unfortunately, there doesn’t seem to be a lowercase available in
ByteString; at the moment it seems that you need to set up your own
ctype table and use that.