大文字・小文字の反転

30分プログラム、その633。anarchy golf - invert caseにインスパイアされました。
単語中の大文字を小文字に、小文字を大文字にする変換。例えば、Fooを与えるとfOOが得られる。
大文字化と小文字化をいい感じに組合せたらできないだろうか、と考えてみたけど、思いつかなかったので諦めて直接変換する関数を書きました。

使い方

*Main> invert "Foo"
"fOO"

ソースコード

import Data.List
import Data.Maybe
invertChar :: Char   -> Char
invert     :: String -> String

upper = ['A'..'Z']
lower = ['a'..'z']

upper2lower = zip upper lower
lower2upper = zip lower upper

invertChar c = head $
               concatMap (\f -> f c) [search upper2lower,
                                      search lower2upper,
                                      \x -> [x]]
    where search xs x = maybeToList $ lookup x xs

invert = map invertChar