{- - Section 3 Solutions - - Do the Challenge problems for yourself! Their solutions will be at the - bottom of this document; best advice would be to do them before looking at - the solutions, but that's up to you -} -- Warmup quad :: Double -> Double -> Double -> Double -> Double quad a b c x = a*x^2 + b*x + c {- - Note that I could rewrite quad to take more general numeric input, like - Integers, but if you pass in Integers to the quad function above, Haskell - will interpret them as Doubles and just "work" anyway. -} -- Question 1 rev :: [a] -> [a] rev [] = [] rev (x : xs) = rev xs ++ [x] {- - There's another, equally stylistically valid way of writing rev; instead of - doing multiple function definitions like above, we could have one function - definition that cases on the input, like so: -} case_rev :: [a] -> [a] case_rev ls = case ls of [] -> [] (x : xs) -> case_rev xs ++ [x] -- Question 2 -- alan_example :: [a] -> [Char] WORKS! -- alan_example :: (a) -> [Char] DOESN'T WORK! -- alan_example :: [Integer] -> [Char] WORKS! alan_example (x : xs) = "something aquatic" -- isOdd :: Integer -> Bool WORKS -- isOdd :: Double -> a DOESN'T WORK -- isOdd :: a -> Bool DOESN'T WORK isOdd x = elem x [1,3..x] -- Note the list comprehension semantics! -- slope :: (Integer, Integer) -> (Integer, Integer) -> Double DOESN'T WORK (why do -- you think it doesn't work?) -- slope :: (Double, Double) -> (Double, Double) -> Double WORKS -- slope :: (Integer, Double) -> (Integer, Double) -> Double DOESN'T WORK slope (x1, y1) (x2, y2) = (y2 - y1) / (x2 - x1) -- my_all (a -> Bool) -> [a] -> Bool WORKS -- my_all (Integer -> Bool) -> [Integer] -> Bool WORKS -- my_all (Integer -> a) -> [Integer] -> Bool DOESN'T WORK my_all p y = case y of [] -> True (x : xs) -> p x && my_all p xs -- Question 3 my_map2 :: (a -> b -> c) -> [a] -> [b] -> [c] my_map2 f [] [] = [] my_map2 f (x : xs) (y : ys) = f x y : my_map2 f xs ys ----------------------------------------------------------------------------------------- {- - Challenges for Warmup, Q1, Q3 - Try to do these on your own before peeking! -} --Warmup - one-tuple quad_challenge :: (Double, Double, Double, Double) -> Double quad_challenge (a, b, c, x) = a*x^2 + b*x + c --Q1 - Double the rev list rev_challenge1 :: Num a => [a] -> [a] rev_challenge1 [] = [] rev_challenge1 (x : xs) = rev_challenge1 xs ++ [(x * 2)] --Q1 - Use Tail Recursion rev_challenge2 :: [a] -> [a] rev_challenge2 ls = tail_rev ls [] tail_rev :: [a] -> [a] -> [a] tail_rev [] acc = acc tail_rev (x : xs) acc = tail_rev xs (x : acc) --Q3 - Double a list using my_map2 double :: Num a => [a] -> [a] double ls = my_map2 (+) ls ls --Q3 - Rewrite my_map2 to take potentially different-length lists challenge_map2 :: (a -> b -> c) -> [a] -> [b] -> [c] challenge_map2 f [] [] = [] challenge_map2 f (x : xs) [] = [] challenge_map2 f [] (y : ys) = [] challenge_map2 f (x : xs) (y : ys) = f x y : challenge_map2 f xs ys