// // Course: BU CAS CS 520, Fall 2010 // Instructor: Hongwei Xi (hwxi AT cs DOT bu DOT edu) // Lecture on Tuesday, Nov 30, 2010 // (* ****** ****** *) datatype tree = E of () | B of (tree, tree) (* ****** ****** *) (* // // HX: Python-style :) // extern fun ht (t: tree): int fun isPerfect (t: tree): bool = case+ t of | B (tl, tr) => isPerfect (tl) andalso isPerfect (tr) andalso (ht(tl) = ht(tr)) | E () => true // end of [isPerfect] *) (* // // HX: C-style :) // fun isPerfect (t: tree): bool = let fun aux (t: tree): int = case+ t of | B (tl, tr) => let val hl = aux (tl) in if hl >= 0 then let val hr = aux (tr) in if hl=hr then hl+1 else ~1 end else ~1 end // end of [B] | E () => 0 in aux (t) >= 0 end // end of [isPerfect] *) (* // // HX: A functional monadic style // fun isPerfect (t: tree): bool = let fun aux (t: tree): Option (int) = case+ t of | B (tl, tr) => (case+ aux(tl) of | Some hl => (case+ aux(tr) of | Some hr => if hl=hr then Some (hl+1) else None () | None () => None () ) | None () => None () ) // end of [B] | E () => Some (0) in case+ aux (t) of | Some _ => true | None () => false end // end of [isPerfect] *) (* // HX: An example of proper use of exception *) fun isPerfect (t: tree): bool = let exception NotPerfect of () fun aux (t: tree): int = case+ t of | B (tl, tr) => let val hl = aux (tl) and hr = aux (tr) in if hl = hr then hl + 1 else $raise (NotPerfect) end // end of [B] | E () => 0 // end of [aux] in try let val _ = aux (t) in true end with ~NotPerfect () => false // end of [try] end // end of [isPerfect] (* ****** ****** *) (* end of [exception.dats] *)