(* F# examples seen in class *) (* Algebraic data types *) (* aka Discriminated Unions *) type mood = Happy | Sad | Mad let m = Happy let f = function Happy -> "\n:-)\n" | Sad -> "\n:-(\n" | _ -> "\n:-@\n" System.Console.WriteLine (f Happy) System.Console.WriteLine (f Sad) System.Console.WriteLine (f Mad) (* boolean algebra *) type Proposition = | True | Not of Proposition | And of Proposition * Proposition | Or of Proposition * Proposition let prop : Proposition = Or(True,Not(True)) let rec eval x = match x with | True -> true // syntax: Pattern-to-match -> Result | Not(prop) -> not (eval prop) | And(prop1, prop2) -> (eval prop1) && (eval prop2) | Or(prop1, prop2) -> (eval prop1) || (eval prop2) (* binary tree *) type btree = | Empty | Node of (btree * int * btree) Empty let e = Empty let t3 = Node(e,3,e) let t5 = Node (e, 5, e) let t9 = Node (t3,9,t5) let t4 = Node(t9,4,e) t4 (* t4 corresponds to this tree: (4) / \ (9) () / \ / \ (3) (5) / \ / \ () () () () *) let newTree n = Node(Empty, n, Empty) newTree 10 // Extracts value of root node if t is a non-empty tree let rootValue t = match t with Node (_, v, _) -> v | _ -> failwith "Empty tree" t3 rootValue t3 rootValue e // Extracts left subtree if t is non-empty let leftChild t = match t with Node (t, _, _) -> t | _ -> failwith "Empty tree" t3 leftChild t3 t9 leftChild t9 // Extracts right subtree if t is non-empty let rightChild t = match t with Node (_, _, t) -> t | _ -> failwith "Empty tree" // returns true iff integer n occurs in tree t let rec occurs n t = match t with Empty -> false | Node (t1, m, t2) -> (m = n) || (occurs n t1) || (occurs n t2) t4 occurs 10 t4 occurs 9 t4 // "inserts" integer n in tree t so that // all nodes to the left have a smaller or equal value let rec insert n t = match t with Empty -> newTree n | Node (t1, m, t2) -> if (n < m) then Node (insert n t1, m, t2) else Node (t1, m, insert n t2) let s = Node (Empty, 3, Node (Empty, 6, Empty)) (* (3) / \ () (6) / \ () () *) let s1 = insert 4 s (* (3) / \ () (6) / \ (4) () / \ () () *) let s2 = insert 5 s1 (* (3) / \ () (6) / \ (4) () / \ () (5) / \ () () *) // collects all integer values in tree t into a list let rec traverse t = match t with Empty -> [] | Node (t1, m, t2) -> let l1 = traverse t1 in let l2 = traverse t2 in l1 @ [m] @ l2 traverse s2