diff --git a/lab04/lab.lhs b/lab04/lab.lhs index 58e2eb9..4680d84 100644 --- a/lab04/lab.lhs +++ b/lab04/lab.lhs @@ -6,9 +6,8 @@ First, implement your own version of the foldl function, defined as myFoldl > myFoldl :: (a -> b -> a) -> a -> [b] -> a -> myFoldl _ _ _ = error "TBD" > myFoldl f acc [] = acc -> myFoldl f acc (x:xs) = f acc $ myFoldl f x xs +> myFoldl f acc (x:xs) = myFoldl f (f acc x) xs Next, define a function to reverse a list using foldl. @@ -20,7 +19,6 @@ Next, define a function to reverse a list using foldl. Now define your own version of foldr, named myFoldr > myFoldr :: (a -> b -> b) -> b -> [a] -> b -> myFoldr _ _ _ = error "TBD" > myFoldr f acc [] = acc > myFoldr f acc (x:xs) = f x $ myFoldr f acc xs @@ -28,10 +26,13 @@ Now define your own version of foldr, named myFoldr Now try using foldl (the library version, not yours) to sum up the numbers of a large list. Why is it so slow? +foldl is slow because it repeatedly pushes unevaluated expressions on the stack + Instead of foldl, try using foldl'. Why is it faster? (Read http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl%27 for some hints) +foldl' evaluates the accumulator at each step, preventing the build up of unevaluated expressions For an extra challenge, try to implement foldl in terms of foldr. See http://www.haskell.org/haskellwiki/Foldl_as_foldr for details. @@ -40,11 +41,20 @@ See http://www.haskell.org/haskellwiki/Foldl_as_foldr for details. Next, using the map function, convert every item in a list to its absolute value > listAbs :: [Integer] -> [Integer] -> listAbs _ = error "TBD" +> listAbs = map abs Finally, write a function that takes a list of Integers and returns the sum of their absolute values. > sumAbs :: [Integer] -> Integer -> sumAbs _ = error "TBD" +> sumAbs = sum . listAbs +> main :: IO () +> main = do +> putStrLn $ "myFoldl (+) 0 [1..10] = " ++ show (myFoldl (+) 0 [1..10]) +> putStrLn $ "myReverse [1..5] = " ++ show (myReverse [1..5]) +> putStrLn $ "myFoldr (+) 0 [1..10] = " ++ show (myFoldr (+) 0 [1..10]) +> putStrLn $ "listAbs [-1, -2, 3, -4] = " ++ show (listAbs [-1, -2, 3, -4]) +> putStrLn $ "sumAbs [-1, -2, 3, -4] = " ++ show (sumAbs [-1, -2, 3, -4]) +> putStrLn $ "foldl (+) 0 [1..10000000] = " ++ show (foldl (+) 0 [1..10000000]) +> putStrLn $ "foldl' (+) 0 [1..10000000] = " ++ show (foldl' (+) 0 [1..10000000])