Commit 0b67026b authored by James R. Wilcox's avatar James R. Wilcox
Browse files

L08 prep

parent d2ac348f
(* variant types *)
(* first a couple very simple ones that are just enumerations of possibilities *)
type si_unit =
| Second
| Meter
| Kilogram
| Ampere
| Kelvin
| Mole
| Candela
let ss = [Second; Meter; Second]
let string_of_si_unit (u : si_unit) : string =
match u with
| Second -> "second"
| Meter -> "meter"
| Kilogram -> "kilogram"
| Ampere -> "ampere"
| Kelvin -> "kelvin"
| Mole -> "mole"
| Candela -> "candela"
let sa = string_of_si_unit Ampere
type si_prefix =
| Giga
| Mega
| Kilo
| Milli
| Micro
| Nano
let scale p =
match p with
| Giga -> 1e9
| Mega -> 1e6
| Kilo -> 1e3
| Milli -> 1e-3
| Micro -> 1e-6
| Nano -> 1e-9
let sg = scale Giga
(* Now variant types where one or more constructors carry [typed] data,
which is much more interesting and powerful
*)
type silly =
| A of int * bool * (string list)
| Foo of string
| Pizza
let silly_over_silly s =
match s with
| A(x,y,z) -> List.hd z
| Foo s2 -> s2 ^ s2
| Pizza -> "ham and pineapple"
type shape =
| Circle of float * float * float (* center-x, center-y, radius *)
| Rectangle of float * float * float * float (* x1,y1,x2,y2 (opposite corners) *)
| Triangle of float * float * float * float * float * float (* x1,y1,x2,y2,x3,y3 *)
let area s =
match s with
| Circle (x,y,radius) -> Float.pi *. radius *. radius
| Rectangle (x1,y1,x2,y2) -> Float.abs ((x2 -. x1) *. (y2 -. y1))
| Triangle (x1,y1,x2,y2,x3,y3) ->
let a = x1 *. (y2 -. y3) in
let b = x2 *. (y3 -. y1) in
let c = x3 *. (y1 -. y2) in
Float.abs ((a +. b +. c) /. 2.0)
let well_formed s =
area s > epsilon
let num_straight_sides s =
(* will soon learn better style than these variable names *)
match s with
| Circle (x,y,r) -> 0
| Rectangle (a,b,c,d) -> 4
| Triangle (x1,x2,x3,x4,x5,x6) -> 3
let max_point s =
let rec highest ps = (* local function assumes non-empty list *)
if List.tl ps = [] then
List.hd ps
else
let tl_ans = highest (List.tl ps) in
if snd tl_ans > snd (List.hd ps) then
tl_ans
else
List.hd ps
in
match s with
| Circle (x,y,radius) -> (x, y +. radius)
| Rectangle (x1,y1,x2,y2) -> highest [(x1,y1);(x2,y2)] (* any pt on top edge ok *)
| Triangle (x1,y1,x2,y2,x3,y3) -> highest [(x1,y1);(x2,y2);(x3,y3)]
(* variants can be recursive, describing recursive data structures like trees *)
type expr =
| Constant of int
| Negate of expr
| Add of expr * expr
| Mul of expr * expr
let rec eval e =
match e with
| Constant i -> i
| Negate e1 -> - (eval e1)
| Add (e1, e2) -> (eval e1) + (eval e2)
| Mul (e1, e2) -> (eval e1) * (eval e2)
let rec max_const (e: expr) : int =
let max (x,y) = if x > y then x else y in
match e with
| Constant i -> i
| Negate e1 -> max_const e1
| Add (e1, e2) -> max (max_const e1, max_const e2)
| Mul (e1, e2) -> max (max_const e1, max_const e2)
let rec has_const_not_under_add e =
match e with
| Constant i -> true
| Negate e1 -> has_const_not_under_add e1
| Add (e1,e2) -> false
| Mul (e1, e2) -> has_const_not_under_add e1 || has_const_not_under_add e2
let rec number_of_adds e =
match e with
| Constant i -> 0
| Negate e1 -> number_of_adds e1
| Add (e1, e2) -> 1 + number_of_adds e1 + number_of_adds e2
| Mul (e1, e2) -> number_of_adds e1 + number_of_adds e2
let example_exp = Add (Constant 19, Negate (Constant 4))
let example_ans = eval example_exp
let example_addcount = number_of_adds (Mul (example_exp,example_exp))
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