[Haskell-cafe] Re: Suspected stupid Haskell Question

Chad Scherrer chad.scherrer at gmail.com
Wed Oct 17 13:35:10 EDT 2007

Big_Ham <joymachine2001 <at> hotmail.com> writes:

> Is there a library function to take a list of Strings and return a list of
> ints showing how many times each String occurs in the list.
> So for example:
> ["egg", "egg", "cheese"] would return [2,1]
> I couldn't find anything on a search, or anything in the librarys.
> Thanks BH.

Hi BH,

This might be overkill, but it works well for me. And it avoid stack overflows I
was originally getting for very large lists. Dean Herrington and I came up with

ordTable :: (Ord a) => [a] -> [(a,Int)]
ordTable xs = Map.assocs $! foldl' f Map.empty xs
    where f m x = let  m' = Map.insertWith (+) x 1 m
                       Just v = Map.lookup x m'
                  in v `seq` m'

intTable :: [Int] -> [(Int,Int)]
intTable xs = IntMap.assocs $! foldl' f IntMap.empty xs
    where f m x = let  m' = IntMap.insertWith (+) x 1 m
                       Just v = IntMap.lookup x m'
                  in v `seq` m'

enumTable :: (Enum a) => [a] -> [(a,Int)]
enumTable = map fstToEnum . intTable . map fromEnum
    where fstToEnum (x,y) = (toEnum x, y)

If you like, it's easily wrapped in a Table class.


More information about the Haskell-Cafe mailing list