2

Hi I am a beginner to haskell. I am trying to get the first 3 items from this tuple list:

[("and",2),("cat",1),("dog",1),("rabbit",1),("the",2)]

First I sort the list by frequency and descending order:

sortWords =  sortBy(flip compare `on` snd)

This gives me the result:

[("and",2),("the",2),("cat",1),("dog",1),("rabbit",1)]

Then I know I can do the function:

take 3 [("and",2),("the",2),("cat",1),("dog",1),("rabbit",1)] 

which gives me the desired result of [("and",2),("the",2),("cat",1)]

However, I want to be able to incorporate the take function into the sortWords function. The problem is, when I attempt to do this, for example:

sortWords =  take 3 (sortBy(flip compare `on` snd))

this does not work.

Ideally, I want to keep sortWords as the end function so I do not want to pass it into another to be able to perform the take function. If there's a way to perform take before calling sortWords that could be a solution, however I have also tried this and found that the words which are taken are not sorted first and therefore do not give me the result I want.

Thank you

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
k1r4n
  • 69
  • 2
  • 12

1 Answers1

7

The problem here is that sortBy (flip compare `on` snd) is not a list of tuples, it is a function that takes as input a list of tuples and returns a list of tuples.

We can use the function composition operator (.) :: (b -> c) -> (a -> b) -> a -> c:

sortWords :: Ord b => [(a,b)] -> [(a,b)]
sortWords = take 3 . sortBy (flip compare `on` snd)

here we thus first will apply sortBy (flip compare `on` snd) on the input, and then we will apply take 3 on the output of that function.

Alexis King
  • 43,109
  • 15
  • 131
  • 205
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555