summaryrefslogtreecommitdiffstats
path: root/sort.sml
blob: 407619f3d2eae197bfc22d25b08f4932f2c94f93 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
signature SORT =
sig
  val sort : ('a * 'a -> order) -> 'a list -> 'a list
end

structure Sort :> SORT =
struct
  fun split (l : 'a list, n : int) : ('a list * int) * ('a list * int) =
    let val h = n div 2
    in ((l, h), (List.drop (l, h), n - h))
    end

  fun merge (_ : 'a * 'a -> order) ([] : 'a list) (l2 : 'a list) : 'a list = l2
    | merge _ l1 [] = l1
    | merge cmp (xl as x :: xs) (yl as y :: ys) =
        (case cmp (x, y) of
          GREATER => y :: merge cmp xl ys
        | _ => x :: merge cmp xs yl)

  fun sort' (cmp : 'a * 'a -> order) (s as (l : 'a list, n : int)) : 'a list =
    if n < 2 then List.take (l, n) else
    let
      val (first, second) = split s
      val firstSorted = sort' cmp first
      val secondSorted = sort' cmp second
    in merge cmp firstSorted secondSorted
    end

  fun sort (cmp : 'a * 'a -> order) (l : 'a list) : 'a list = sort' cmp (l, length l)
end