From 767a9c67780a3282b51ed83e62da435ed9301bec Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Thu, 22 Jan 2026 12:33:05 -0800 Subject: [PATCH] add lecture 03 notes --- lecture03/notes03.ml | 214 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 lecture03/notes03.ml diff --git a/lecture03/notes03.ml b/lecture03/notes03.ml new file mode 100644 index 0000000..2a56749 --- /dev/null +++ b/lecture03/notes03.ml @@ -0,0 +1,214 @@ +(* PARTIAL FUNCTIONS - because it does not return a value in + some cases *) + +let hd l = + match l with + | [] -> failwith "hd: empty list" + | x:: _ -> x;; + +let tl l = + match l with + | [] -> failwith "tl: empty list" + | _ :: xs -> xs;; + +(* associative list is a list of pairs *) +let al = [("a123", 55); ("b456", 67)];; + +(** [find k l] returns a value v from a key [k] in a list of pairs [l] + * fails if not found + *) +let rec find k l = + match l with + | [] -> failwith "find: key not found" + | (k', v') :: _ when k = k' -> v' + | _ :: xs -> find k xs;; + +(* + best case is to have a TOTAL FUNCTION, always return a value + this can be accomplished with an option type, that has two + variants, either None or Some e.g. None;; Some 2;; +*) + +(** [find_opt k l] returns an optional value v from a key [k] in a list of pairs [l] *) +let rec find_opt k l = + match l with + | [] -> None + | (k', v') :: _ when k = k' -> Some v' + | _ :: xs -> find_opt k xs;; + +(*** HIGHER ORDER FUNCTIONS ***) + +(** [insert x l] inserts element [x] into list [l] + * Requires: [l] is in ascending order. *) +let rec insert x l = + match l with + | [] -> [x] + | y :: ys -> + if x <= y then x :: l + else y :: insert x ys;; + +(* Note: the following insert is the same logically, just shorter *) +(** [insert x l] inserts element [x] into list [l] + * Requires: [l] is in ascending order. *) +let rec insert x l = + match l with + | y :: ys when x > y -> y :: insert x ys + | _ -> x :: l + +(** [insertion_sort l] sorts list [l] in ascending order *) +let rec insertion_sort l = + match l with + | [] -> [] + | x :: xs -> insert x (insertion_sort xs) + +(*** ANONYMOUS FUNCTIONS ***) +(* fun x -> x * x;; <-- syntax*) +let f' x = x * x;; + +(* these functions are equivalent *) +let a = fun x y -> x + y;; (* func that takes two params *) +let a' x = fun y -> x + y;; (* func taht takes 1 param and returns a func that takes 1 param *) + +let s x = x * x;; +(* f 2 + 3;; (* result: 7 *) +f (2 + 3);; (* result: 25 *) +f @@ 2 + 3;; (* result: 25 *) *) + +let rec insertion_sort l = + match l with + | [] -> [] + | x :: xs -> insert x @@ insertion_sort xs;; + +(* function is short form of "l = match l with ..." *) +let rec insertion_sort = function + | [] -> [] + | x :: xs -> insert x @@ insertion_sort xs;; + +let inc x = x + 1;; +let square x = x * x;; +let add x y = x + y;; + +square (inc 1);; (* r = 4 *) +square @@ inc 1;; (* r = 4 *) +1 |> inc |> square;; (* pipe operator - r = 4 or <|*) +1 |> inc |> square |> add 2;; (* r = 6 *) + +let flip f x y = f y x;; +let sub x y = x - y;; +flip sub 1 2;; (* flips two arguments, becomes sub 2 1 *) + +(** [map f l] for each element in list [l] apply func [f] + * return list of [l] with func [f] applied to elems *) +let rec map f l = + match l with + | [] -> [] + | x :: xs -> f x :: map f xs;; + +map (fun x -> x * x) [1; 2; 3; 4; 5; 6];; +map int_of_string_opt ["1"; "2"; "3"; "z"];; + +(** [filter f l] for each element in list [l] keep + * element if it passes predicate func [f] *) +let rec filter f l = + match l with + | [] -> [] + | x :: xs when f x -> x :: filter f xs + | _ :: xs -> filter f xs;; + +filter (fun x -> x mod 2 = 0) [1; 2; 3; 4; 5; 6; 7; 8; 9];; +["a"; "1"; "2"] |> map int_of_string_opt |> filter (function | None -> false | Some _ -> true) (* filter out None *) +(* list gets piped into the snd arg of map and result of map is piped to snd arg of filter *) +(* pipes can go left also? <| *) + +(** [take_while f l] returns the longest prefix of [l] each of its elements + * satisfying [f] *) +let take_while f l = + let rec aux l acc = + match l with + | [] -> List.rev acc + | x :: xs -> + if f x then aux xs (x :: acc) + else List.rev acc + in + aux l [];; + +take_while (fun x -> x mod 2 = 0) [3; 2; 6; 6; 8];; +take_while (fun x -> x mod 2 = 0) [2; 6; 7; 6; 8];; +take_while (fun x -> x mod 2 = 0) [2; 6; 6; 8];; + +(** [take_while f l] returns the longest prefix of [l] each of its elements + * satisfying [f] *) +let take_while f l = + let rec aux l acc = + match l with + | x :: xs when f x -> aux xs (x :: acc) + | _ -> List.rev acc + in + aux l [];; + +take_while (fun x -> x mod 2 = 0) [3; 2; 6; 6; 8];; +take_while (fun x -> x mod 2 = 0) [2; 6; 7; 6; 8];; +take_while (fun x -> x mod 2 = 0) [2; 6; 6; 8];; + + + +(* + cmp x y < 0 x before y + = 0 doesnt matter, x = y + > 0 x after y +*) + +let rec insert' cmp x l = + match l with + | [] -> [x] + | y :: ys -> + if cmp x y <= 0 then x :: l + else y :: insert' cmp x ys;; + +let rec sort' cmp l = + match l with + | [] -> [] + | x :: xs -> + insert' cmp x @@ sort' cmp xs;; + +sort' Int.compare [3;2;7;6;8];; +sort' (Fun.flip Int.compare) [3;2;7;6;8];; + +(* with labeled arguments *) +let rec insert'' ~cmp x l = + match l with + | [] -> [x] + | y :: ys -> + if cmp x y <= 0 then x :: l + else y :: insert'' ~cmp x ys;; + +let rec sort'' ~cmp l = + match l with + | [] -> [] + | x :: xs -> + insert'' ~cmp x @@ sort'' ~cmp xs;; + +(* labeled arguments can go anywhere *) +sort'' [3;2;7;6;8] ~cmp:Int.compare;; +sort'' ~cmp:(Fun.flip Int.compare) [3;2;7;6;8];; + +(* process list from left to right *) +(* fold_left -> (((acc $ x1) $ x2) $ x3) *) +let rec fold_left f acc l = + match l with + | [] -> acc + | x :: xs -> fold_left f (f acc x) xs;; + +fold_left (fun acc x -> acc + x) 0 [3; 2; 7; 6; 8];; +fold_left (+) 0 [3; 2; 7; 6; 8];; +(+) 1 3;; (* makes + act like a function *) + +(* process list from right to left *) +(* fold_right -> (x1 $ (x2 $ (x3 $ acc))) *) +let rec fold_right f l acc = + match l with + | [] -> acc + | x :: xs -> f x (fold_right f xs acc);; + +fold_left min max_int [3; 2; 7; 6; 8];; +fold_right min [3; 2; 7; 6; 8] max_int;;