Haskell - Counting how many times each distinct element in a list occurs

夙愿已清 提交于 2021-02-05 20:27:37

问题


I'm new to Haskell and am just trying to write a list comprehension to calculate the frequency of each distinct value in a list, but I'm having trouble with the last part..

So far i have this:

frequency :: Eq a => [a] -> [(Int,a)] 
frequency list = [(count y list,y) | y <- rmdups ]

Something is wrong with the last part involving rmdups.

The count function takes a character and then a list of characters and tells you how often that character occurs, the code is as follows..

count :: Eq a => a -> [a] -> Int
count x [] = 0
count x (y:ys) | x==y = 1+(count x ys)
               | otherwise = count x ys

Thank-you in advance.


回答1:


You could also use a associative array / finite map to store the associations from list elements to their count while you compute the frequencies:

import Data.Map (fromListWith, toList)

frequency :: (Ord a) => [a] -> [(a, Int)]
frequency xs = toList (fromListWith (+) [(x, 1) | x <- xs])

Example usage:

> frequency "hello world"
[(' ',1),('d',1),('e',1),('h',1),('l',3),('o',2),('r',1),('w',1)]

See documentation of fromListWith and toList.




回答2:


I had to use Ord in instead of Eq because of the use of sort

frequency :: Ord a => [a] -> [(Int,a)] 
frequency list = map (\l -> (length l, head l)) (group (sort list))



回答3:


As requested, here's a solution using Control.Arrow:

frequency :: Ord a => [a] -> [(Int,a)] 
frequency = map (length &&& head) . group . sort

This is the same function as ThePestest's answer, except

λ f g l -> (f l, g l)

is replaced with

-- simplified type signature
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)

from Control.Arrow. If you want to avoid the import,

liftA2 (,) :: Applicative f => f a -> f b -> f (a, b)

works as well (using the Applicative instance of (->) r)




回答4:


Assuming rmdups has the type

rmdups :: Eq a => [a] -> [a]

Then you're missing a parameter for it.

frequency :: Eq a => [a] -> [(Int,a)] 
frequency list = [(count y list,y) | y <- rmdups list]

But the error you're getting would be helpful with diagnosis.




回答5:


Your rmdups function is just nub from Data.List.




回答6:


Replacing rmdups with nub list worked for me like a charm.




回答7:


Hahahaha there is an rmdups on pg. 86 of Programming in Haskell by Graham Hutton. It is perfect and recursive. It is also handy in a great many situations.

Here is my one line rmdups and it produces the same results as nubor Hutton's.

rmdups ls = [d|(z,d)<- zip [0..] ls,notElem d $ take z ls]

It can well be used to count distinct elements of a list.

dl = "minimum-maximum"
[ (d,sum [1|x<-dl,d == x]) | d<-rmdups dl]

[('m',6),('i',3),('n',1),('u',2),('-',1),('a',1),('x',1)]



来源:https://stackoverflow.com/questions/10398698/haskell-counting-how-many-times-each-distinct-element-in-a-list-occurs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!