Challenge: find the top three most frequently used words in a string. Only imports from the
base package are allowed (source: codewars)
I'm looking for feedback on (1) readability, and (2) performance
- Was folding the string into "frequency map" a good choice?
- I have several small functions that I compose together. Are these abstraction layers helping or hurting readability?
- How are my functions names?
- Does the
basepackage have any libraries that would make this code significantly easier to write?
- Could I benefit from using more pointfree style?
import qualified Data.Map as Map import Data.List import Data.Function import Data.Char import Data.Maybe top3 :: [Char] -> [[Char]] top3 str = let wordFrequencyMap = foldr (Map.alter increment) Map.empty (normalizedWords str) sortedWordFrequencies = sortBy reverseBySecond (Map.toList wordFrequencyMap) in map fst (take 3 sortedWordFrequencies) where normalizedWords = filter containsAtLeastOneAlphaNumericChar . lowerCaseWords . map isLegalChar containsAtLeastOneAlphaNumericChar w = find isAlphaNum w /= Nothing lowerCaseWords = map (map toLower) . words isLegalChar c = if isAlphaNum c || c =='\'' then c else ' ' reverseBySecond x y = if snd x < snd y then GT else LT increment Nothing = Just 1 increment (Just x) = Just (x + 1)