1
\$\begingroup\$

OK... last sort of the day and probably the most fun. F# is really awesome.

let rec quickSort list = 
    match list with
    | [] -> []
    | [x] -> [x]
    | hd :: _ -> 
        quickSort (List.filter (fun x -> x < hd) list) @ hd :: quickSort (List.filter (fun x -> x > hd) list)

[<EntryPoint>]
let main args = 
    printfn "%s" (List.fold (fun acc x -> acc + " " + x.ToString()) "" (quickSort [10; 7; 1; 0; -1; 9; 33; 12; 6; 2; 3; 33; 34;]))
    0

let me know How I can improve this code. I am trying to think functionally and want my program to be most efficient, concise and functional.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ This will probably drop any duplicate elements as x !< hd and x !> hd \$\endgroup\$ Dec 22, 2013 at 10:41
  • \$\begingroup\$ I do have a question though. since I make 2 calls to quickSort in the recursion... will these two calls be made parallelly? I have heard that functional languages are more multi-core friendly... but want to confirm if I have to do some thing explicilty to ensure that all the two sub quickSorts are executed on different threads. \$\endgroup\$ Dec 22, 2013 at 18:20
  • \$\begingroup\$ The calls will not run on separate threads. This is good as you could generate a lot of threads if itndid \$\endgroup\$ Dec 22, 2013 at 19:21
  • \$\begingroup\$ OK... but they say that functional languages are more multi-core friendly as compared to imperative ones. so in the program above is there any multi-core benefit which I would not get in a traditional langugae.... also is there something I can do to be more multicore aware? \$\endgroup\$ Dec 22, 2013 at 19:26
  • 1
    \$\begingroup\$ @KnowsNotMuch You can use normal .Net Tasks for that. Something like Task.Run(fun () -> quickSort ...) to start two Tasks and then call Result on both of them to get the results. \$\endgroup\$
    – svick
    Dec 25, 2013 at 15:16

1 Answer 1

2
\$\begingroup\$

I'd:

  • exclude unnecessary duplication (List.filter etc.)
  • drop separate match rule for the list of one element
  • rely on type inference
  • use more succinct form of pattern matching

Something like this:

let rec qsort = function
    | [] -> []
    | x::xs -> let lt, ge = List.partition ((>) x) xs
               qsort lt @ x :: qsort ge
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.