- Open src/Main.hs and add the following definitions to it. For each function such as sum, we will create two versions--sumr, which uses foldr, and suml, which uses foldl.
- Use both, right and left folds to sum up the numerical contents of a list to write functions sumr and suml as follows:
sumr :: Num a => [a] -> a
sumr xs = foldr (+) 0 xs
suml :: Num a => [a] -> a
suml xs = foldl (+) 0 xs
- Similarly, use right and left folds to calculate product of all elements in the list. This should results in functions productr and productl respectively:
productr :: Num a => [a] -> a
productr xs = foldr (*) 1 xs
productl :: Num a => [a] -> a
productl xs = foldl (*) 1 xs
- Define map using the folds mapr and mapl:
mapr :: (a -> b) -> [a] -> [b]
mapr f xs = foldr (\x result -> f x : result) [] xs
mapl :: (a -> b) -> [a] -> [b]
mapl f xs = foldl (\result x -> f x : result) [] xs
Note how an anonymous function is defined (\x result -> f x : result). This is called lambda function. Its syntax is \ arg1 arg2 ... -> <body of the lambda>. The backslash \' is an abbreviation of the Greek letter lambda!
- Define the filter using the folds filterr and filterl:
filterr :: (a -> Bool) -> [a] -> [a]
filterr f xs = foldr filtered [] xs
where
filtered x result
| f x = x : result
| otherwise = result
filterl :: (a -> Bool) -> [a] -> [a]
filterl f xs = foldl filtered [] xs
where
filtered result x
| f x = x : result
| otherwise = result
Test the functions that we defined in the main function:
main :: IO ()
main = do
let input = [1..10]
square x = x * x
putStrLn "Calculating sum of [1..10]"
putStrLn " Using foldr"
putStrLn (show $ sumr input)
putStrLn " Using foldl"
putStrLn (show $ suml input)
putStrLn "Calculating product of [1..10]"
putStrLn " Using foldr"
putStrLn (show $ productr input)
putStrLn " Using foldl"
putStrLn (show $ productl input)
putStrLn "Squaring [1..10] using map"
putStrLn " Using foldr"
putStrLn (show $ mapr square input)
putStrLn " Using foldl"
putStrLn (show $ mapl square input)
putStrLn "Filtering odd elements [1..10] using filter"
putStrLn " Using foldr"
putStrLn (show $ filterr odd input)
putStrLn " Using foldl"
putStrLn (show $ filterl odd input)
- Build the project using stack build and run it. You should see the following output:
