Nested Patterns

Posted by Beetle B. on Wed 10 August 2016

We can nest patterns as deep as we like. Anywhere we put a variable in our pattern, we can put another pattern.

exception BadTriple

fun zip3 list_triple =
  case list_triple of
      ([], [], []) => []
    | (hd1::tl1, hd2::tl2, hd3::tl3) => (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)
    | _ => raise BadTriple

fun unzip3 lst =
  case lst of
      [] => ([], [], [])
    | (a, b, c)::tl =>
      let val (l1, l2, l3) = unzip3 tl
      in (a::l1, b::l2, c::l3)
      end

fun is_sorted intlist =
  case intlist of
      [] => true
    | _::[] => true
    | head::(neck::rest) => (head <= neck andalso nondecreasing (neck::rest))


a::(b::(c::d))  (* Match lists with 4 or more elements *)

a::(b::(c::[])) (* Match lists with exactly 3 elements *)

(a, b, c)::d    (* Match a list of triplets. *)

Note that _ is a wildcard: It matches anything, but does not bind it to anything.

If you ever have a nested case, consider if nested patterns will work instead.