# Functional Programming, Continued --- CS 135 // 2021-02-23 # Lab 3 - Due on Thursday before class - An **individual** lab rather than a group one - Any questions? # Questions ## ...about anything? # Functional Programming ## Functional Programming - Since functional programming avoids the use of side effects, we depend on the following features to get things done: + Recursion (for repetition) + Currying (partial application) + Higher-order functions + Lambda expressions (anonymous functions) # Self Checks ## Check 6 - How many arguments does `drop 2` take? ## Check 7 - What does this function do? ```haskell f (_:x:_) = x ``` --- 1. Returns the first element of a list 2. Returns an arbitrary element of a list 3. Returns all except the first and last elements of a list 4. Returns the second element of a list ## Check 8 - What is the result of the following expression? ```haskell reverse $ take 5 . tail $ "This is a test"` ``` --- 1. `"i sih"` 2. `"set a"` 3. A type error ## Check 9 - If `f :: a -> b`, then what is the type of
`map (.f)`? ```haskell [b -> c] -> [a -> c] -- 1 [c -> a] -> [c -> b] -- 2 (b -> c) -> [a -> c] -- 3 [a] -> [b] -- 4 ``` ## Check 10 - What is the type of the leftmost `id` in `id id`? --- 1. unspecified 2. `a` 3. `a -> a` 4. `(a -> a) -> (a -> a)` ## Check 11 - What is the type of `const const`? --- 1. unspecified 2. `(c -> a -> b) -> a` 3. `c -> (a -> b -> a)` 4. `a -> b -> c -> a` # `case of` ## Pattern Matching, Revisited - Recall that it is possible to pattern match when you are defining a function such as: ```haskell sorted :: [Int] -> Bool sorted [] = True sorted [_] = True sorted (x:y:zs) = x <= y && sorted (y:zs) ``` ## `case of` Pattern Matching - `case EXP of ...` is an expression that allows you to do pattern matching on an arbitrary value ```haskell sorted :: [Int] -> Bool sorted xs = case xs of [] -> True [_] -> True (x:y:zs) -> x <= y && sorted (y:zs) ``` ## Lab 3, Exercise 14 - Implement an interpreter for a simple language - Keep track of the x and y coordinates - Interpret the following commands: + up (increment y by one) + down (decrement y by one) + left (decrement x by one) + right (increment x by one) + printX (print value of x) + printY (print value of y) ## Lab 3, Exercise 14 - The interpreter will be a function: ```haskell interpreter :: [String] -> [String] ``` - Its input is a list of commands, and its output is a list of the results of the print commands in the input - Both coordinates start at 0. - Examples: ```haskell interpreter ["up","up","up","printY","down","printY"] ==> ["3","2"] ``` ```haskell interpreter ["up","right","right","printY","printX"] ==> ["1","2"] ``` # List Comprehensions ## List Comprehensions - In mathematics, we often use expressions like this: + $C = \\{(x,y) \mid x\in A, y\in B, x \ge y\\}$ - If $A = \\{0,1,2,3\\}$ and $B=\\{2,3,4,5\\}$, then + $C = \\{(2,2), (3,2), (3,3)\\}$ - We can use this notation to specify lists in Haskell: ```haskell setA = [0,1,2,3] setB = [2,3,4,5] setC = [(x,y) | x <- setA, y <- setB, x >= y] ``` ## Acronym - Let's write a function that takes a list of strings as a parameter and returns the **acronym** of those strings ```haskell acronym :: String -> String acronym phrase = [head word | word <- words phrase] ``` ```haskell acronym :: String -> String acronym phrase = map head (words phrase) ``` ```haskell acronym :: String -> String acronym = map head . words ``` # Exercises ## Exercise 1 - Define the function `map` from scratch using lists and pattern matching. ```haskell map :: (a -> b) -> [a] -> [b] ``` ## Exercise 2 - Define a version of map that takes a two-argument function and two lists - For example: ```haskell map2 f [x,y,z,w] [a,b,c] -- ==> [f x a, f y b, f z c] ``` - If the lists have differing lengths, ignore the trailing elements of the longer list. ```haskell map2 :: (a -> b -> c) -> [a] -> [b] -> [c] ``` ## Exercise 3 - Implement the function `merge` that merges two sorted lists of integers into a sorted list ```haskell merge :: [Integer] -> [Integer] -> [Integer] ``` - Examples: ```haskell merge [1,3,5] [2,4,6] ==> [1,2,3,4,5,6] ``` ```haskell merge [1,1,6] [1,2] ==> [1,1,1,2,6] ``` ## Exercise 3, Continued - Now with `merge` implemented, we can now implement the classic `mergeSort` algorithm ```haskell mergeSort :: [Integer] -> [Integer] ``` ## Lab Time - Please turn on your camera when in a breakout session if possible - Some students are hard of hearing and rely on lip-reading to follow along in conversation