0

I am trying to implement radix sort in SML via a series of helper functions. The helper function I am having trouble with is called sort_nth_digit, it takes a digit place to be sorted by and a list to sort (n and L respectively). The way I am doing this is to find the first two elements of the list (for now we can assume there are at least 3), compare them by digit n, then concatenating them back onto the list in the proper order. The list should be sorted in ascending order. Now, the problem: The function compiles but I get the following:

HW4.sml:40.5-44.30 Warning: match nonexhaustive (0,L) => ... (n,nil) => ... (n,a :: b :: L) => ...

val sort_nth_digit = fn : int -> int list -> int list

Additionally, when you pass arguments, you don't get an answer back which I believe indicates infinite recursion?

Q:How is the match nonexhaustive and why am I recursing infinitely:

 fun sort_nth_digit 0 L = []
|   sort_nth_digit n [] = []
|       sort_nth_digit n (a::b::L) = if ((nth_digit a n) < (nth_digit b n)) then a::b::(sort_nth_digit n L)
        else
            b::a::(sort_nth_digit n L)

Thanks for the help in advance! (*My first post on stackoverflow ^.^ *)

Nonexhasutive match fix:

fun sort_nth_digit 0 L = []
|   sort_nth_digit n [] = []
|       sort_nth_digit n (a::[]) = a::[]
|       sort_nth_digit n (a::b::L) = if ((nth_digit a n) < (nth_digit b n)) then a::b::(sort_nth_digit n L)
        else
            b::a::(sort_nth_digit n L) 

Input that results in no output, console just sits at this line:

- sort_nth_digit 1 [333,222,444,555,666,444,333,222,999]; 

Code for nth_digit & anonymous helper pow:

fun nth_digit x 0 =  0
|   nth_digit x n = if (num_digits x) < n then 0
        else 
            let 
                fun pow x 1 = x
                |   pow x y= x * pow x (y-1)
            in
(*Finding the nth digit of x: ((x - x div 10^n) * 10^n div 10^n-1))*)
            (x - ((x div pow 10 n) * pow 10 n)) div (pow 10 (n-1))  (*Me*)
            end

If anyone thinks it would be useful to have access to the rest of my code I can provide it via github as an eclipse project (you can just pull the .sml file if you don't have eclipse set up for sml)

  • So I sort of found a solution, it is kinda sloppy and does not fix my original one but here it is: `fun bucket d n [] = [] | bucket d 0 L = [] | bucket d n (a::L) = if ((nth_digit a n) = d) then a::(bucket d n L) else bucket d n L` `'fun sort_nth_digit 0 L = [] | sort_nth_digit n [] = [] | sort_nth_digit n L = if n > 9 then [] else (bucket 0 n L)@(bucket 1 n L)@(bucket 2 n L)@(bucket 3 n L)@(bucket 4 n L)@(bucket 5 n L)@(bucket 6 n L)@(bucket 7 n L)@(bucket 8 n L)@(bucket 9 n L)` – Josh Sonnenberg Feb 22 '14 at 05:57

1 Answers1

0

The match is not exhaustive because it does not cover the case of a list with only one element (and inductively, any list with an odd number of elements).

I'm not sure what you mean by "not getting an answer". This function does not diverge (recurse infinitely), unless your nth_digit helper does. Instead, you should get a Match exception when you feed it a list with odd length, because of the above.

Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
  • So how would I indicate a list with only one element? Would it just be `sort_nth_digit n a::nil =a` ? The reason that I thought it was infinitely recursive is because when I gave the function some input it did not return any output and I couldn't enter any further commands into the console. nth_digit should not be diverging as it works properly independently of sort_nth_digit and I don't see how calling the function from sort_nth_digit would change that? Thanks for the response! – Josh Sonnenberg Feb 23 '14 at 22:21
  • Yes, that sounds like it's diverging somehow. But I don't see how the function you gave can be the cause of that. Can you show us your `nth_digit` helper, and the input that causes divergence? – Andreas Rossberg Feb 24 '14 at 07:37
  • I don't know if you get an update when I edit my post so fyi, I added the info that you requested. Additionally I think i fixed the nonexhastive match issue. – Josh Sonnenberg Feb 24 '14 at 22:43
  • Your `pow` function is the problem. It diverges when y <= 0. Since you call it with y = n-1 in a case where n may be 1, that triggers it. – Andreas Rossberg Feb 25 '14 at 08:11
  • Whups, it seems so obvious now! Thanks a lot for the help! – Josh Sonnenberg Feb 25 '14 at 15:30