2012-05-01 19 views
8

Jestem nowy w Haskell i próbuję po prostu napisać listę ze zrozumieniem, aby obliczyć częstotliwość każdej odrębnej wartości na liście, ale mam problem z ostatnia część ..Haskell - Zliczanie ile razy każdy odrębny element na liście występuje

do tej pory mam to:

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

Coś jest nie tak z ostatniej części obejmującej rmdups.

Funkcja count przyjmuje postać i po listę znaków i mówi, jak często zdarza się, że postać, kod jest w następujący sposób ..

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

Thank-ty z góry.

+7

Tak, „coś jest nie tak z częścią ostatniej udziałem rmdups”, ale nie powiesz nam, co jest błędny, jaki (jeśli w ogóle) komunikat o błędzie lub dane wyjściowe otrzymasz, a ty nie pokazujesz definicji (lub nawet samego typu) 'rmdups'. Jak mamy odpowiedzieć? – delnan

+0

Przepraszam, że napisałem tam rmdup, kiedy faktycznie miałem na myśli nub – user1353742

Odpowiedz

0

Twoja funkcja rmdups to tylko nub z Data.List.

10

musiałem użyć Ord w zamiast Eq powodu użycia sort

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

Używanie 'Control.Arrow',' frequency = map (length &&& head). Grupa . sort' – cdk

+0

@cdk Wydaje się to interesujące. Nie mógłbyś rozwinąć tego w odpowiedzi na to pytanie? –

4

Zakładając rmdups ma typ

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

Wtedy tracisz parametr dla niego.

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

Ale błąd, który otrzymujesz, byłby pomocny przy diagnozie.

0

Zastępując rmdups z nub list pracował dla mnie jak urok.

10

Można również użyć tablicy asocjacyjnej/skończoną mapę do przechowywania skojarzenia z listy elementów do ich liczby podczas obliczania częstotliwości:

import Data.Map (fromListWith, toList) 

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

Przykład użycia:

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

widoczny na dokumentację fromListWith i toList.

6

Zgodnie z wnioskiem, oto rozwiązanie wykorzystujące Control.Arrow:

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

Jest to taka sama funkcja, jak odpowiedź ThePestest „s, z wyjątkiem

λl -> (length l, head l) 

otrzymuje z

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

z Control.Arrow.Jeśli chcesz uniknąć importu,

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

działa tak samo (za pomocą aplikacyjnych wystąpienie (->) r)

+0

Jeśli ktoś szuka gotowego rozwiązania, istnieje metoda 'count' w [' Data.List.Unique'] (https://hackage.haskell.org/package/Unique-0.4.7.2 /docs/Data-List-Unique.html). Implementacja jest dość podobna do tej podanej w tej odpowiedzi. –

Powiązane problemy