Key phone in Haskell
In real code, I would consider this to be too much naming for this little code. Most of this would probably be used only once and could thus be inlined. Since the exercise required implementations for all these, it's okay.

(concat .) . map is foldMap.

\x y -&gt; compare (length x) (length y) is comparing length.

Did you try compiling this? ind /= Nothing means that ind + 1 shouldn't work, and elemIndex takes the Char before the String.

look keys c = case asum $ zipWith (fmap . (,)) [0..] $ map (elemIndex c) keys of
  Nothing -&gt; []
  Just (n, ind) -&gt; [(head $ show n, ind + 1)]