Here is my solution for an exercise, which requires translation of strings to key presses on a phone keypad (for example, to get 'b' the digit '2' needs to be pressed twice).
It's taken from the book Haskell from first principles, and originally appeared in 1HaskellADay. I'd love to get feedback.
module Phone where import Data.Char import Data.String.Utils import Data.List data DaPhone = DaPhone [String] convo :: [String] convo = ["Wanna play 20 questions", "Ya", "U 1st haha", "Lol ok. Have u ever tasted alcohol lol", "Lol ya", "Wow ur cool haha. Ur turn", "Ok. Do u think I am pretty Lol", "Lol ya", "Haha thanks just making sure rofl ur turn"] -- validButtons = "1234567890*#" type Digit = Char -- Valid presses: 1 and up type Presses = Int reverseTaps :: DaPhone -> Char -> [(Digit, Presses)] reverseTaps (DaPhone keys) c = if isUpper c then ('*', 1) : looks else looks where looks = look keys (toLower c) -- assuming the default phone definition -- 'a' -> [('2', 1)] -- 'A' -> [('*', 1), ('2', 1)] look :: [String] -> Char -> [(Digit, Presses)] look keys c = look' keys c 0 look' :: [String] -> Char -> Int -> [(Digit, Presses)] look'  _ _ =  look' (x:xs) c n = if ind /= (-1) then [(head $ show n, ind + 1)] else look' xs c (n + 1) where ind = maybe (-1) id $ elemIndex c x cellPhonesDead :: DaPhone -> String -> [(Digit, Presses)] cellPhonesDead = (concat .) . map . reverseTaps -- count total presses fingerTaps :: [(Digit, Presses)] -> Presses fingerTaps = sum . map snd mostPopularLetter :: String -> Char mostPopularLetter = head . longest . group . sort coolestLtr :: [String] -> Char coolestLtr = mostPopularLetter . filter isAlpha . concat coolestWord :: [String] -> String coolestWord = head . longest . group . sort . words . join " " longest :: [[a]] -> [a] longest = maximumBy (\x y -> compare (length x) (length y)) phone :: DaPhone phone = DaPhone keymap keymap :: [String] keymap = [ " 0", "1", "abc2", "def3", "ghi4", "jkl5", "mno6", "pqrs7", "tuv8", "wxyz9" ]