(* CSE 341, Spring 2011 *)
(* Lecture 6: nested pattern-matching *)
exception BadTriple
(* don't do this *)
fun old_zip3 (l1,l2,l3) =
if null l1 andalso null l2 andalso null l3
then []
else if null l1 orelse null l2 orelse null l3
then raise BadTriple
else (hd l1, hd l2, hd l3)
:: old_zip3(tl l1, tl l2, tl l3)
(* don't do this *)
fun shallow_zip3 (l1,l2,l3) =
case l1 of
[] =>
(case l2 of
[] => (case l3 of
[] => []
| _ => raise BadTriple)
| _ => raise BadTriple)
| hd1::tl1 =>
(case l2 of
[] => raise BadTriple
| hd2::tl2 => (case l3 of
[] => raise BadTriple
| hd3::tl3 =>
(hd1,hd2,hd3)::shallow_zip3(tl1,tl2,tl3)))
(* do this (or use function patterns) *)
fun zip3 list_triple =
case list_triple of
([],[],[]) => []
| (hd1::tl1,hd2::tl2,hd3::tl3) =>
(hd1,hd2,hd3)::zip3(tl1,tl2,tl3)
| _ => raise BadTriple
(* and the inverse *)
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
(* another elegant use of "deep" patterns
(even better with 'as' pattern) *)
fun nondecreasing intlist =
case intlist of
[] => true
| x::[] => true
| hd::(next::tl) => (hd <= next andalso nondecreasing (next::tl))
(* nested pattern-matching often convenient even without recursion;
also the wildcard pattern is good style
match on a pair and one or more parts of it very useful on homework 2
*)
datatype sign = P | N | Z
fun multsign (x1,x2) =
let fun sign x = if x=0 then Z else if x>0 then P else N
in
case (sign x1,sign x2) of
(Z,_) => Z
| (_,Z) => Z
| (P,P) => P
| (N,N) => P
| _ => N (* many say bad style; I am okay with it *)
end
fun revp(lst: int list) =
let fun aux([],acc) = acc
| aux(x::xs,acc) = aux(xs,x::acc)
in
aux(lst,[])
end