- String concatenation is not commutative but it is associative - "Hello" ^ "World" <> "World" ^ "Hello". String concatenation is not commutative - "Hello" ^ ("World" ^ "Mars") = ("Hello" ^ "World") ^ "Mars" String concatenation is associative Aka. The parenthesis don't matter - Distinguishing fold_left from fold_right Signatures: List.fold_left : ('a -> 'b -> 'a) -> 'a -> 'b list -> 'a List.fold_right : ('a -> 'b -> 'b) -> 'a list -> 'b -> 'b Test: List.fold_left (fun acc le -> acc ^ le) "" ["H"; "e"; "l"; "l"; "o"] List.fold_right (fun le acc -> acc ^ le) ["H"; "e"; "l"; "l"; "o"] "" Predictions: Left-to-right dataflow: "Hello" Right-to-left dataflow: "olleH" Result: fold_left causes left-to-right df fold_right causes right-to-left df Failed distinguisher: Exponentiation **: fold_left (**) 2 [3; 4] (2^3)^4 = 2^(3*4) = 2^(4*3) = (2^4)^3 Subtraction -: (2 - 3) - 4 = 2 - (3 + 4) = 2 - (4 + 3) = (2 - 4) - 3 Division / : (2 / 3) / 4 = 2 / (3 * 4) = 2 / (4 * 3) = (2 / 4) / 3 String concatenation: "a" ^ "b" ^ "c" <> "acb" Another distinguishing operator: (23 mod 4) mod 3; (23 mod 3) mod 4 List.fold_left (fun acc le -> acc mod le) 23 [4; 3] ==>* 0 List.fold_right (fun le acc -> acc mod le) [4; 3] 23 ==>* 2 List.fold_left (mod) 23 [4; 3] ==>* 0 List.fold_right (mod) [4; 3] 23 ==>* 1 let rec fold_left f acc l = match l with | [] -> acc | hd :: tl -> fold_left f (f acc hd) tl let rec fold_right f l acc = match l with | [] -> acc | hd :: tl -> f hd (fold_right f tl acc) - map, filter, fold, group_by, ... map, ..., reduce, ====================================================== Introducing Mutable State - Haskell the language was supposed to be "pure" "Pure" = There is _no_ way to change state The same expression always evaluates to the same value A pure program has no way of influencing the world IO Monad, Simon Peyton Jones and Philip Wadler "State of the World" "Action of producing an output": IO Monad - printf, print_int, print_char, ... read_line, ... ====================================== - Two ways to change the value of a variable - ref field, similar to pointers in C-like languages - mutable fields inside records - type 'a ref = { mutable contents: 'a } let ref a = { contents = a } !a is really shorthand for a.contents a := 3 is really shorthand for a.contents <- 3 - a.name <- "SomethingElse" - Efficient algorithm implementation ==================================== Semicolons in Ocaml - In the toplevel: ;; Line terminator In lists of elements: [1; 2; 3] Element separator In records: Element separator - (e1; e2): - The semicolon, (e1; e2), is a binary operator which: - Evaluate e1. e1 may have side effects. That's ok - Throw away the value produced by e1. - Evaluate e2. Return its value. (x := 3; !x) - Also similar to the comma operator from C