This is something I threw together in my spare time at work to play with Data.ByteString. I'm sure there are things that could be done better; please improve as you wish and leave notes and reasoning on this page. Thanks!
- B.group is apparently quite slow. Perhaps it would be faster to do something like:
[CharCount n (B.count n s) | n <- ['A'..'Z'], s <- strings] -- or [B.foldl' (\cl c -> updateAssocListSomehow c) s  | s <- strings]
[CharCount]representation may not be the most efficient. A 27 integer UArray could be faster. Then again, I haven't profiled the code and wasn't aiming for raw speed, so.. *shrug*
I tried Data.IntMap on a lark, and while it doesn't complicate the code much, it was a slight slow-down. Might be because I tested for subset then did a difference... not sure how to do it in one step.