Commit 3fe42bc3 authored by James R. Wilcox's avatar James R. Wilcox
Browse files

sec03.ml

parent fe09b1c0
(* Welcome to Section 3! *)
(* This file contains the answers to the section Exercises & more *)
let fst3 (x,_,_) = x (* gets the first element of a triple *)
let snd3 (_,x,_) = x (* gets the second element of a triple *)
let thd3 (_,_,x) = x (* gets the third element of a triple *)
(**** 1. Type Synonyms ****)
(* Synonym for dates in Day, Month, Year format *)
type date = int * int * int
let date1 : int * int * int = (22, 2, 1900)
let date2 : date = (11, 1, 1900)
let date3 = (17, 1, 2019)
(* Convert date format from (Day, Month, Year) to (Month, Day, Year) *)
let dmy_to_mdy (d : int * int * int) =
(snd3 d, fst3 d, thd3 d)
(* B. For dates: *)
let dmy_to_mdy2 (d : date) =
(snd3 d, fst3 d, thd3 d)
(* C. Don't forget to test your code as you go!!! (see sec2_test.ml) *)
(**** 2. Type Generality ****)
(* A. Append two string lists *)
(* Type: string list * string list -> string list *)
let rec append ((xs : string list), (ys : string list)) =
if xs = []
then ys
else List.hd xs :: append (List.tl xs, ys)
(* B. What types of list will this function work for?
All list types!!!
*)
(* Type: 'a list * 'a list -> 'a list *)
let rec append (xs, ys) =
if xs = []
then ys
else List.hd xs :: append (List.tl xs, ys)
let list1 = ["hi"; "bye"]
let list2 = ["programming"; "languages"]
let list3 = [1; 2]
let list4 = [3; 4; 1]
(* C. Write 3 calls to append - two should pass one should cause a type error *)
let okay1 = append (list1, list2)
let okay2 = append (list4, list3)
(* let not_okay = append (list1, list3) *)
(* Generality Examples: Which one is more general? *)
(*
1. a) 'a list * 'a list -> 'b list
b) int list * int list -> string list
2. a) 'a list * 'a list -> 'b list
b) int list * int list -> int list
3. a) 'a list * 'a list -> 'b list
b) int list * string list -> int list
4. a) 'a list * 'a list -> 'a list
b) 'a list * 'a list -> 'b list
5. type foo = int * int
a) int list * foo -> foo list
b) int list * (int * int) -> (int * int) list
*)
(* Answers:
1. a
2. a
3. Neither - Type 'b cannot be used in place of type 'a!
4. b
5. Both/Neither - They are the same type!
*)
(**** 3. Variant Types and Pattern-Matching ****)
type cart = float * float
type shape = Circle of cart * float (* coordinates and radius *)
| Square of cart * float (* coordinates and side length *)
| Rectangle of cart * float * float (* coordinates and side lengths *)
let area sh =
match sh with
Circle(c, r) -> Float.pi *. r *. r
| Square(c, s) -> s *. s
| Rectangle(c, w, l) -> w *. l
(* Here's another nice example showing how pattern
matching can be readable, concise, and powerful *)
type exp = Constant of int
| Negate of exp
| Add of exp * exp
| Multiply of exp * exp
let rec eval e =
match e with
Constant i -> i
| Add(e1, e2) -> (eval e1) + (eval e2)
| Negate e1 -> - (eval e1)
| Multiply(e1, e2) -> (eval e1) * (eval e2)
let rec const_not_under_add e =
match e with
Constant i -> true
| Negate e1 -> const_not_under_add e1
| Add (e1,e2) -> false
| Multiply(e1, e2) -> const_not_under_add e1 || const_not_under_add e2
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment