To determine which case of a function applies to a value, merely apply the matching algorithm to each argument pattern until you get a match. (For multi-argument functions, treat the argument tuple as a single argument.)
- fun silly(0, y) = y | silly(x, y) = 1 + silly(x-1, y); val silly = fn : int * int -> int - val my_tuple = (3,4); val my_tuple = (3,4) : int * int - silly(my_tuple); val it = 7 : int
In practice, pattern-matching function arguments is usually so intuitive that you don't have to think consciously about the algorithm. Consider the following function to reverse the elements of a list, and its translation to pattern-matching style:
fun reverse(x) = if null(x) then nil else reverse(tl(x)) @ [hd(x)]; fun reverse(nil) = nil | reverse(x::xs) = reverse(xs) @ [x];
You can transform many functions into tail-recursive equivalents by using a simple trick: add one or more extra parameters that represent "the work that you have done so far". Here's tail-recursive reverse:
fun reverse(x) = let fun rev(nil, rev_so_far) = done | rev(x::xs, rev_so_far) = rev(xs, x::rev_so_far); in rev(x, nil) end;