import Data.Char charSucc :: Char -> (Char, Bool) charSucc c | isDigit c = charSucc' '0' '9' c | isUpper c = charSucc' 'A' 'Z' c | isLower c = charSucc' 'a' 'z' c | otherwise = (c, True) where charSucc' low high c | c == high = (low, True) | otherwise = (succ c, False) successor :: String -> String successor = finish . foldr step ("", True) where step c (rest, False) = (c : rest, False) step c (rest, True ) = (s : rest, carry) where (s, carry) = charSucc c finish (s, False) = s finish (s@('0':_), True) = '1' : s finish (s@('a':_), True) = 'a' : s finish (s@('A':_), True) = 'A' : s finish (s, _) = s