Filter Duplicate Elements in Haskell I'm working on HackerRank to try to improve my Haskell skills along side with reading Haskell Programming from first principles. I wrote a program that works, but it seems to time out on large input sets. The purpose of the program is

Given a list of n integers a = [a1, a2, ..., an], you have to find those integers which are repeated at least k times. In case no such element exists you have to print -1.
If there are multiple elements in a which are repeated at least k times, then print these elements ordered by their first occurrence in the list.

So I wrote a few different functions to help with this.
count which counts the number of occurrences of an element in a list
count :: Eq a =&gt; Integral b =&gt; a -&gt; [a] -&gt; b
count e [] = 0
count e (a:xs) = (count e xs +) $ if a == e then 1 else 0

uniq which removes duplicates from a list
uniq :: Eq a =&gt; [a] -&gt; [a] -&gt; [a]
uniq x [] = x 
uniq [] (a:xs) = uniq [a] xs
uniq x (a:xs) = if a `elem` x then uniq x xs else uniq (a:x) xs 

filt which filters through a list and removes elements that don't occur at least k times.
filt :: Show a =&gt; Num a =&gt; Read a =&gt; Eq a =&gt; Integral b =&gt; [a] -&gt; b -&gt; [a]
filt a b = reverse $ uniq [] [i | i &lt;- a, count i a &gt;= b]

printList which prints a list as a space separated list or prints -1 if the list is empty.
printList :: Show a =&gt; [a] -&gt; IO ()
printList [] = putStrLn &quot;-1&quot;
printList a = putStrLn $ unwords [show i | i &lt;- a] 

readNumbers which takes a space separated string and returns a Num list from that string.
readNumbers :: Show a =&gt; Eq a =&gt; Num a =&gt; Read a =&gt; String -&gt; [a]
readNumbers = map read . words

run which throws all of this together and runs this n times.
run :: (Show a, Eq a, Num a, Read a) =&gt; a -&gt; IO ()
run 0 = putStr &quot;&quot;
run n = do
  a &lt;- getLine
  b &lt;- getLine
  printList $ filt (readNumbers b) (readNumbers a !! 1)
  run $ n - 1

main the main function. It gets a number n and then calls run n.
main :: IO ()
main = do
  a &lt;- getLine
  run $ read a

This code works, for example, with the input
3
9 2
4 5 2 5 4 3 1 3 4
9 4
4 5 2 5 4 3 1 3 4
10 2
5 4 3 2 1 1 2 3 4 5

and gives the desired output of
4 5 3
-1
5 4 3 2 1

However, with larger datasets this code is incredibly slow. I'm guessing it's because the recursion is less than optimal, but I can't really pinpoint what is taking so long. My best guess is that uniq or count is the limiting factor, but I can't figure out how to optimize them.
If you write uniq as a right fold, you don't need to pass an accumulator through, and the list comes out in the right order:

uniq :: Eq a =&gt; [a] -&gt; [a]
uniq [] = []
uniq (x:xs) = (if x `elem` xs then id else (x:)) $ uniq xs

filt :: Show a =&gt; Num a =&gt; Read a =&gt; Eq a =&gt; Integral b =&gt; [a] -&gt; b -&gt; [a]
filt k is = uniq [i | i &lt;- is, count i is &gt;= k]


(Edit: Actually that one throws out the first of each two equal elements, not the last. Here`s one without that problem:

uniq :: Eq a =&gt; [a] -&gt; [a]
uniq [] = []
uniq (x:xs) = x : uniq (filter (/=x) xs)


)

You've commendably already brought count into a form that allows it to be written in terms of library combinators:

count :: Eq a =&gt; Integral b =&gt; a -&gt; [a] -&gt; b
count e = sum . map (\a -&gt; if a == e then 1 else 0)


That's a bit ugly due to lambdas though, here's a nicer version:

count e = length . filter (== e)


For separation of monadic and pure code (and generally for factoring out common code from across cases), here's a showList to replace printList:

showList :: Show a =&gt; [a] -&gt; String
showList [] = "-1"
showList a = unwords [show i | i &lt;- a] 


Calling a monadic action a given number of times doesn't need manual recursion, and thus also doesn't need to give the repeated action a name:

main :: IO () 
main = do
  a &lt;- readLn
  replicateM_ a $ do
    [_n, k] &lt;- map read . words &lt;$&gt; getLine
    numbers &lt;- map read . words &lt;$&gt; getLine
    putStrLn $ showList $ filt k numbers


(I think readNumbers doesn't deserve a name.)

In case the order in which the output is given isn't important, here's a version that doesn't require quadratic time because each element is compared to every other:

filt k = map head . filter ((&gt;=k) . length) . group . sort


which relies on Data.Lists sort being faster than quadratic time.