(*
Max Sherman
CSE 341
todo:
1. Shadowing bindings demo
2. Pattern matching review
3. polymorphism and equality types
4. Homemade data types
*)
(* shadowing demo *)
val q = 3
fun what_is_q () = q
val q = 4
(* pattern matching review *)
(* sum a list *)
fun sumlist (xs : int list) =
case xs of
[] => 0
| x::xs' => x + sumlist xs'
(* assoc -- return option on first matched pair's value *)
fun assoc (xs : (string * int) list, k : string) =
case xs of
[] => NONE
| (key,v)::xs' => if k = key then SOME v else assoc (xs', k)
(* remove duplicates in a sorted list *)
fun dedupe (xs : int list) =
case xs of
[] => []
| [x] => [x]
| hd::nk::xs' => if hd = nk
then dedupe (nk::xs')
else hd :: dedupe (nk :: xs')
(* polymorphism *)
(* sml will infer the most general type it can if unconstrained *)
(* for example, reverse and id. What should these types be? *)
fun id x = x
fun rev xs =
case xs of
[] => []
| x::xs' => rev xs' @ [x]
(* equality types *)
(* duplicates in a sorted list but more general *)
fun dedupe_general xs =
case xs of
[] => []
| [x] => [x]
| hd::(nk::xs') => if hd = nk
then dedupe_general (nk::xs')
else hd :: dedupe_general (nk :: xs')
(* to really illustrate the point *)
fun isEqual (x,y) = x = y
(* what is the type of this? *)
fun are_both_equal (a,b,x,y) = a = b andalso x = y
(* homemade data types *)
(* data ---> type synonym, and datatype ---> new type *)
type person_record = { first:string
, middle:string
, last:string
, ssid:int
}
type address_book = person_record list
fun sum_ages (ab : address_book) =
case ab of
[] => 0
| {first=_,middle=_,last=_,ssid=n}::ab' => n + sum_ages ab'
datatype tree =
Node of int * tree * tree
| Leaf of int
val tr = Node (5,Node (2,Leaf 1,Leaf 3),Leaf 7)
fun collapse t =
case t of
Leaf i => [i]
| Node (i, l, r) => (collapse l) @ (i :: collapse r)