fun printList(L) =
   let
      fun length(M) =
        if (M=nil) then 0
        else 1+length(tl(M));

      fun printListHelper (0, _, _) = (print "[]\n"; nil)
      |   printListHelper (_, 0, _) = (print "]\n"; nil)
      |   printListHelper (_, _, nil) = (print "[]\n"; nil) (* Can't happen *)
      |   printListHelper (len, left, x::xs) =
         if(len = left) then (print "["; print (Int.toString(x)); printListHelper(len, left-1, xs))
         else (print ", "; print (Int.toString(x)); printListHelper(len, left-1, xs));

      val len = length(L);
   in
      printListHelper(len, len, L)
   end;

fun halve nil = (nil, nil)
|   halve [a] = ([a], nil)
|   halve (a::b::cs) =
      let
        val (x, y) = halve cs
      in
        (a::x, b::y)
      end;

fun merge (nil, ys) = ys
|   merge (xs, nil) = xs
|   merge (x::xs, y::ys) =
      if (x < y) then x :: merge(xs, y::ys)
      else y :: merge(x::xs, ys);

fun mergeSort nil = (printList([]); nil)
|   mergeSort [a] = (printList([a]); [a])
|   mergeSort theList =
      let
        val (x, y) = halve theList
      in
        (printList(theList);
        merge(mergeSort x, mergeSort y))
      end;