There's a little-known function from Data.List called nub. It's particularly good for code golfing.
import Data.List
exactlyOneVowel :: String -> Bool
exactlyOneVowel = (== 1) . length . nub . sort . filter (`elem` "aeiouyAEIOUY")
 I believe this satisfies all the constraints of the problem, and is unfortunately O(#characters ^ 2).