Reputation: 13
I got the task to count the number of occurrences of each (lower case) character in a string. I am not allowed to use any function of the library, I came up with the following, working solution.
occur :: String -> [(Char,Int)]
occur y = [ (x,count x y) | x<-['a'..'z'], count x y > 0]
I was trying at first:
occur2 :: String -> [(Char,Int)]
occur2 y = [ (x,z) | x<-['a'..'z'], z<- count x y, count x y > 0]
I defined the helper function count like this:
count :: Char -> String -> Int
count k str = length [n | n <- str, n == k]
Two questions:
Upvotes: 1
Views: 103
Reputation: 33466
occur2
isn't working because count x y
is not a list, so it can't be used for a generator expression like in z <- count x y
. Instead, use a let
expression.
You can remove the count
definition by inlining it.
occur :: String -> [(Char,Int)]
occur y = [ (x,z) | x <- ['a'..'z'], let z = length [n | n <- y, n == x], z > 0]
If you were to use libraries, a simple and efficient implementation would be to use a MultiSet
.
import qualified Data.MultiSet as MS
occur :: String -> [(Char,Int)]
occur = MS.toAscOccurList . MS.fromList . filter (\c -> c >= 'a' && c <= 'z')
Upvotes: 2