#include "BUCASCS320.hats"
#define :: list0_cons
#define cons list0_cons
#define nil list0_nil
datatype person =
| King
| Peer of (string, string, int)
| Knight of string
| Peasant of string
fun title (p: person): string = case+ p of
| King () => "His Majesty the King"
| Peer (deg, terr, _) => "The " + deg + " of " + terr
| Knight name => "Sir " + name
| Peasant name => name
fun superior (p1: person, p2: person): bool =
case+ (p1, p2) of
| (King (), Peer _) => true
| (King (), Knight _) => true
| (King (), Peasant _) => true
| (Peer _, Knight _) => true
| (Peer _, Peasant _) => true
| (Knight _, Peasant _) => true
| (_, _) => false
datatype degree = Duke | Marquis | Earl | Viscount | Baron
fun lady (deg: degree): string = case+ deg of
| Duke () => "Duchess"
| Marquis () => "Marchioness"
| Earl () => "Countess"
| Viscount () => "Viscountess"
| Baron () => "Baroness"
exception Empty
fun{a:t@ype} hd (xs: list0 a): a = case+ xs of
| list0_cons (x, _) => x | list0_nil () => $raise Empty
fun{a:t@ype} tl (xs: list0 a): list0 a = case+ xs of
| list0_cons (_, xs) => xs | list0_nil () => $raise Empty
exception Subscript
fun{a:t@ype} nth (xs: list0 a, i: int): a = case+ xs of
| list0_cons (x, xs) => if i > 0 then nth (xs, i-1) else x
| list0_nil () => $raise Subscript
exception Change
fun backChange (coinvals: list0 int, amount: int): list0 int =
case+ (coinvals, amount) of
| (_, 0) => nil ()
| (nil (), _) => $raise Change ()
| (c :: coinvals, amount) =>
if amount < 0 then $raise Change ()
else try
c :: backChange (c :: coinvals, amount - c)
with
| ~Change () => backChange (coinvals, amount)
datatype tree (a:t@ype) = Lf(a) of () | Br(a) of (a, tree a, tree a)
fun comptree (k: int, n: int): tree int =
if n = 0 then Lf ()
else Br (k, comptree (2 * k, n-1), comptree (2 * k + 1, n-1))
fun{a:t@ype} reflect (t: tree a): tree a = case+ t of
| Lf () => Lf ()
| Br (v, t1, t2) => Br (v, reflect<a> t2, reflect<a> t1)
fun{a:t@ype} preorder (t: tree a): list0 a =
case+ t of
| Br (v, t1, t2) => v :: (preorder t1 + preorder t2)
| Lf () => nil ()
fun{a:t@ype} inorder (t: tree a): list0 a =
case+ t of
| Br (v, t1, t2) => inorder t1 + (v :: inorder t2)
| Lf () => nil ()
fun{a:t@ype} postorder (t: tree a): list0 a =
case+ t of
| Br (v, t1, t2) => postorder t1 + (postorder t2 + (v :: nil ()))
| Lf () => nil ()
fun{a:t@ype} balpre (xs: list0 a): tree a = case+ xs of
| x :: xs => let
val k = list0_length<a> xs / 2 in
Br (x, balpre (list0_take_exn (xs, k)), balpre (list0_drop_exn (xs, k)))
end | nil () => Lf ()
fun{a:t@ype} balin (xs: list0 a): tree a = case+ xs of
| x :: xs => let
val k = list0_length<a> xs / 2
val- y :: ys = list0_drop_exn (xs, k)
in
Br (y, balin (list0_take_exn (xs, k)), balin ys)
end | nil () => Lf ()
implement main () = let
in
end