What are nested patterns?

What are nested patterns? I can't understand why the following has nested patterns:

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

Also, I can't understand what is different between nested pattern and nested case-expression can i get some example about those things?

3 Answers

A nested pattern is a pattern that contains other non-trivial patterns (where by "non-trivial" I mean "not a variable or wildcard pattern").

([], [], []) is a nested pattern because (p1, p2, p3) is a pattern (matching tuples) and [] is also a pattern (matching empty lists), which is here applied to the elements of the triple. Likewise (hd1::tl1, hd2::tl2, hd3::tl3) is a nested pattern because (p1, p2, p3) is a pattern and hd1::tl1, hd2::tl2 and hd3::tl3 are also patterns (matching non-empty lists).

A way to express the same thing without nested patterns would be to move the inner patterns into their own case expressions (though I wouldn't recommend it because, as you can see, it makes the code quite a bit more complicated):

case list_triple of
(x, y, z) => case x of [] => case y of [] => case z of [] => [] | _ => raise BadTriple | _ => raise BadTriple | hd1 :: tl1 => case y of [] => raise BadTriple | h2 :: tl2 => case z of [] => raise BadTriple | h3 :: tl3 => (hd1,hd2,hd3)::zip3(tl1,tl2,tl3)

This is a nested case expression because we have a case expression that contains other case-expressions. The version with the nested patterns was not a nested case expression because there was only one case expression - not multiple inside each other.

Maybe it will help if we decompose the function into curry style, which does not have nested patterns, in the foo function below there is only 3 (non-nested) patterns,

fun foo [] [] [] = [] | foo (hd1::tl1) (hd2::tl2) (hd3::tl3) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3) | foo _ _ _ = raise BadTriple
and zip3 (l1, l2, l3) = foo l1 l2 l3

it is easy to see each individual pattern when we use the as keyword, to the right of each as is a pattern.

fun zip3 (l1 as [], l2 as [], l3 as []) = [] | zip3 (l1 as hd1::tl1, l2 as hd2::tl2, l3 as hd3::tl3) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3) | zip3 _ = raise BadTriple

So, why do we consider this nesting?

we can add the as for the initial argument list_triple, and see that we in fact have patterns within a pattern.

fun zip3 (list_triple as (l1 as [], l2 as [], l3 as [])) = [] | zip3 (list_triple as (l1 as hd1::tl1, l2 as hd2::tl2, l3 as hd3::tl3)) = (hd1, hd2, hd3)::zip3(tl1, tl2, tl3)

without as and the unused variables it will look much nicer.

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

what is nested patterns?

pattern in pattern is nested pattern.


I can't understand why it is nested patterns

| (hd1::tl1,hd2::tl2,hd3::tl3) => ...
  • pattern here: (list1, list2, list3)

  • nested pattern here: list1 -> hd1::tl1, list2 -> hd2::tl2, list3 -> hd3::tl3


| (a,b,c)::tl =>
  • pattern here: tuple::t1

  • nested pattern here: tuple -> (a, b, c)

Also i can't understand what is different between nested pattern and nested case-expression can i get some example about those things?


They are two different things. Nested pattern has been explained above. As for nested case-expression:

case something of (*case here*)
| pattern => case pattern of (*nested case here*) | ...

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like