(* Goal for today: more practice with Ocaml. In particular, we'll be starting to see the power of higher order functions. Agenda: * records, tuples and lists * options * higher order functions *) type employee = {name:string ; married:bool; age:int} (* 0a. Make a function that makes a string * int * bool into an employee and vice versa *) (* let employee_of_tuple t = let tuple_of_employee e = *) (* 0b. Why doesn't the expression below type check? How can you make * it typecheck with one small change to the declaration of get_name? *) (* let why = "" let how = "" type employer = {name:string; est_year:int } let get_name e = e.name let g : employee = employee_of_tuple ("Greg", 12, true) let _ = print_string (get_name g) *) (* 0c. Reimplement the OCaml standard functions List.length and List.rev *) (* let length (l:'a list) : int = let rev (l:'a list) : 'a list = *) (* 0d. Remove the kth element from a list. Assume indexing from 0 *) (* example: rmk 2 ["to" ; "be" ; "or" ; "not" ; "to" ; "be"] * results in: [["to" ; "be" ; "not" ; "to" ; "be"] *) (* let rmk (k:int) (l:'a list) : 'a list = *) (* Exercise 1 : Options and Options in functions *) (* 1a. Write a function to return the smaller of two int options, or None * if both are None. If exactly one argument is None, return the other. Do * the same for the larger of two int options.*) (* let min_option (x: int option) (y: int option) : int option = *) (* let max_option (x: int option) (y: int option) : int option = *) (* 1b. Write a function that returns the integer buried in the argument * or None otherwise *) (* let get_option (x: int option option option option) : int option = *) (* 1c. Write a function to return the boolean AND/OR of two bool options, * or None if both are None. If exactly one is None, return the other. *) (* let and_option (x:bool option) (y: bool option) : bool option = *) (* let or_option (x:bool option) (y: bool option) : bool option = *) (* What's the pattern? How can we factor out similar code? *) (* 1d. Write a higher-order function for binary operations on options. * If both arguments are None, return None. If one argument is (Some x) * and the other argument is None, function should return (Some x) *) (* What is calc_option's function signature? *) (* let calc_option (f: 'a->'a->'a) (x: 'a option) (y: 'a option) : 'a option = *) (* 1e. Now rewrite the following functions using the above higher-order function * Write a function to return the smaller of two int options, or None * if both are None. If exactly one argument is None, return the other. *) (* let min_option2 (x: int option) (y: int option) : int option = *) (* let max_option2 (x: int option) (y: int option) : int option = *) (* 1f. Write a function that returns the final element of a list, if it exists, and None otherwise *) (* let final (l: 'a list) : 'a option = *)