(* 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 tup_to_rec ?? = ;; let rec_to_tup ?? = ;; *) (* 0b. Why doesn't the expression below type check? What small change * can you make to it so that it does *) (* type employer = {name:string; est_year:int };; let g : employee = tup_to_rec ("Greg", 12, true);; g.name = "Ada";; print_string g.name;; *) (* 0c. Reimplement the OCaml standard functions List.length and List.rev *) let length (l:'a list) : int = failwith "unimplemented" ;; let rev (l:'a list) : 'a list = failwith "unimplemented" ;; (* 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 = failwith "unimplemented" ;; (* 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 = failwith "unimplemented";; let max_option (x: int option) (y: int option) : int option = failwith "unimplemented";; (* 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 = failwith "unimplemented";; (* 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 = failwith "unimplemented";; let or_option (x:bool option) (y: bool option) : bool option = failwith "unimplemented";; (* 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 = failwith "unimplemented";; (* 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 = failwith "unimplemented";; let max_option2 (x: int option) (y: int option) : int option = failwith "unimplemented";; (* 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 = failwith "unimplemented";; ;;