Implementing a tail recursive version of quicksort-like function in F#/OCaML

后端 未结 3 1484
谎友^
谎友^ 2020-12-09 13:49

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

3条回答
  •  温柔的废话
    2020-12-09 14:07

    Continuation monad (stolen from here) can also be used (usually makes code more readable):

    type ContinuationMonad() =
        // ma -> (a -> mb) -> mb
        member this.Bind (m, f) = fun c -> m (fun a -> f a c)
        // a -> ma
        member this.Return x = fun k -> k x
        // ma -> ma
        member this.ReturnFrom m = m
    let cont = ContinuationMonad()
    
    // Monadic definition of QuickSort
    // it's shame F# doesn't allow us to use generic monad code
    // (we need to use 'cont' monad here)
    // otherwise we could run the same code as Identity monad, for instance
    // producing direct (non-cont) behavior
    let rec qsm = function
         |[]    -> cont.Return []
         |x::xs -> cont {
            let l,r = List.partition ((>=)x) xs
            let! ls = qsm l 
            let! rs = qsm r
            return (ls @ x :: rs) }
    
    // Here we run our cont with id
    let qs xs = qsm xs id     
    
    printf "%A" (qs [2;6;3;8;5;1;9;4])
    

提交回复
热议问题