Quick sort with a predicate I want to pass a predicate into quick sort. The issue I'm running into is that the predicate must have two arguments, the pivot and the element of the list's tail. As far as I know though, predicates can only have 1 argument. Here's what I have so far (it runs, I just want to improve it):

import Data.List

quicksort :: [a] -&gt; (a -&gt; a -&gt; Bool) -&gt;  [a]
quicksort [] _ = []
quicksort (x:xs) pf = quicksort left pf ++ [x] ++ quicksort right pf
    where   pred = pf x
            pt = partition pred xs
            left = fst pt
            right = snd pt
As 200 said, the predicate should be first. Think of filter, takeWhile, dropWhile and similar functions. They take the predicate first.

Also, it's usually a good idea to get rid of arguments that get repeated in every recursive call. GHC should take care of that, but we can help it a little bit:

quicksort :: (a -&gt; a -&gt; Bool) -&gt; [a] -&gt; [a]
quicksort pf = go
  where
    go [] = []
    go (x:xs) = go left ++ [x] ++ go right
      where (left, right) = partition (comp x) xs


However, we're sorting. Therefore calling the comparison function a  predicate is a misnomer. A predicate is a function a -&gt; Bool, whereas a -&gt; a -&gt; Bool is a comparison. But a -&gt; a -&gt; Bool doesn't convey its meaning by its type. Do we return True if the first shall come first in the sorted arrangement? Or do we return False? Will quickSort (&gt;) sort ascending or descending?

Those questions are easier to answer if we use a -&gt; a -&gt; Ord instead. This signature follows compare's, so we have a pretty good feeling what x `compare` y = LT means, namely that x &lt; y holds true.

If we keep that in mind, we can write the following variants:

quicksortBy :: (a -&gt; a -&gt; Ord) -&gt; [a] -&gt;  [a]
quicksortBy comp = go
  where
    go []     = []
    go (x:xs) = go lesser ++ (x : equal) ++ go greater
      where
        (lesser, equal, greater) = partitionOrd (`comp` x) xs

quicksort :: Ord a =&gt; [a] -&gt; [a]
quicksort = quicksortBy compare


The definition of partitionOrd :: (a -&gt; Ord) -&gt; [a] -&gt; ([a], [a], [a]) is left as an exercise. Other than that, well done. Keep in mind that this isn't really Quicksort, though.