0

I don't realize why q's type is Ord t => [t] -> [a] and not Ord a => [a] -> [a]

q [] = []
q (x:xs) = q us ++ q ws
  where us = filter (<=x) xs
        ws = filter (>=x) xs

Under which circumstances the input type could differ from the output?

Thanks,
Sebastián.

bheklilr
  • 53,530
  • 6
  • 107
  • 163
Fof
  • 407
  • 2
  • 8
  • 1
    What happens if you try to sort a list with this implementation? There's a very good reason why it has that type. Try executing `q [1, 3, 2]`, can you tell me why you get that output? – bheklilr May 05 '14 at 20:48
  • 3
    One of the few cases where omitting the signature actually resulted in a helpful hint to the bug, rather than a more confusing error! – leftaroundabout May 05 '14 at 20:58
  • @bheklilr For any input the output is [], that output is because in every step you remove the first element of the input. – Fof May 05 '14 at 21:00
  • 1
    @Seba, correct, I was hoping that if you saw that, it might give you a clue as to what was wrong with your implementation, although leftaroundabout has provided the solution already. – bheklilr May 05 '14 at 21:03

1 Answers1

4

Under any circumstances, which here implies: the function is never useful.

This is actually a nice example of "theorems for free". Obviously, the type Ord t => [t] -> [a] doesn't make much sense, because the only list you can produce of a type [a] (you know nothing about a!) is the empty list. So this proves that q can do only two things:

  • Return []
  • Not terminate (i.e., )

And indeed the former is what happens: in each recursion step, you pop off an element from the input list, but you never actually include any of these elements in the result. So you always end up with [].

If you'd correctly implemented the quicksort, you'd of course bring x back between the two sublists, i.e.

q (x:xs) = q us ++ [x] ++ q ws
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319