// Code adapted from Lec2.ml with minimal changes. // This is *not* idiomatic F# code. type choice<'a,'b> = Left of 'a | Right of 'b;; type btree = Tip | Node of int * btree * btree type repr = (int * (int * btree * btree * btree option) option) option type interm1 = (choice) option type interm2 = (choice) option let step1r (t : btree) : interm1 = match t with | Tip -> None | Node (x, t1, Tip) -> Some (Left (x, t1)) | Node (x, t1, Node (y, t2, t3)) -> Some (Right (x, y, t1, t2, t3)) let step1l (r : interm1) : btree = match r with | None -> Tip | Some (Left (x, t1)) -> Node (x, t1, Tip) | Some (Right (x, y, t1, t2, t3)) -> Node (x, t1, Node (y, t2, t3)) let step2r (r : interm1) : interm2 = match r with | None -> None | Some (Left (x, Tip)) -> Some (Left x) | Some (Left (x, Node (y, t1, t2))) -> Some (Right (x, y, t1, t2, None)) | Some (Right (x, y, t1, t2, t3)) -> Some (Right (x, y, t1, t2, Some t3)) let step2l (r : interm2) : interm1 = match r with | None -> None | Some (Left x) -> Some (Left (x, Tip)) | Some (Right (x, y, t1, t2, None)) -> Some (Left (x, Node (y, t1, t2))) | Some (Right (x, y, t1, t2, Some t3)) -> Some (Right (x, y, t1, t2, t3)) let step3r (r : interm2) : repr = match r with | None -> None | Some (Left x) -> Some (x, None) | Some (Right (x, y, t1, t2, t3opt)) -> Some (x, Some (y, t1, t2, t3opt)) let step3l (r : repr) : interm2 = match r with | None -> None | Some (x, None) -> Some (Left x) | Some (x, Some (y, t1, t2, t3opt)) -> Some (Right (x, y, t1, t2, t3opt)) let iso1 (t : btree) : repr = step3r (step2r (step1r t)) let iso2 (r : repr) : btree = step1l (step2l (step3l r)) (* Shorter forms using function composition: *) (* *) let iso2short = step1l << step2l << step3l let iso1short = step1r >> step2r >> step3r (* *)