Is it possible to implement a tail recursive version of the quick sort algorithm (via the continuation pattern)? And if it is, how would one implement it?
Normal (no
Quick attempt, seeems to work:
let rec quicksort list cont =
match list with
| [] -> cont []
| element::[] -> cont [element]
| pivot::rest ->
let ``elements smaller than pivot``, ``elements larger or equal to pivot`` =
rest |> List.partition (fun element -> element < pivot)
quicksort ``elements smaller than pivot``
(fun x -> quicksort ``elements larger or equal to pivot`` (fun y -> cont (x @ [pivot] @ y)))
> quicksort [2; 6; 3; 8; 5; 1; 9; 4] id;;
val it : int list = [1; 2; 3; 4; 5; 6; 8; 9]
Edit:
Of course, this code is highly inefficient. I hope nobody will use it in real code.
The code was not difficult to write, but continuations might be difficult to read and can be error-prone (it's easy to forget a call to cont). If you want to play more, you can write a continuation monad (Brian wrote a blog post about it).