0

I am having a problem with pattern matching in an sml program.My code is this:

fun ff (arr, _, [], _) = []
   |ff (arr, 0, (x::xs), ping_list) =ping_list
   |ff (arr, K, (x :: xs), ping_list) =
        (if Array.sub(arr, x)-1 < 1
        then ff(arr, (K-1), xs, (ping_list@[x]))
        else ff(arr, K, xs, (ping_list@[x])))

As you can see after going through the third case of the pattern matching it is possible for both K to be 0 and the third argument list to be [].In this case after running some tests it chooses the first pattern and returns [].

How can i control this?In a case of both K=0 and xs being empty i would like the second pattern to be executed and ping_list to be the result but i would also like to understand how corner cases like this are handled by sml.

Thank you in advance

Pradeep
  • 9,667
  • 13
  • 27
  • 34

2 Answers2

0

You normally have the most generic case as the last case and the most specific case as the top case.

If you want to have K=0 and xs=[] to return ping_list your second case should look like this

|ff (_, 0, (x::[]), ping_list) = ping_list

you don't need to name arr, as you don't use it. And the list should be x::[] if you want to match xs = []

Jochen
  • 193
  • 1
  • 8
0

If you want the same definition for 0 and [] as for 0 and x::xs, you can collapse them to one case for 0 and any list.

But you need to put that clause first in order to avoid matching the general empty-list case:

fun ff (_, 0, _, ping_list) = ping_list
  | ff (_, _, [], _) = []
  | ff (arr, K, x::xs, ping_list) =
        if Array.sub(arr, x)-1 < 1
        then ff(arr, K-1, xs, ping_list@[x])
        else ff(arr, K, xs, ping_list@[x])
molbdnilo
  • 64,751
  • 3
  • 43
  • 82