-- D. Sannella. M Fourman, H. Peng and P. Wadler -- Introduction to Computation: Haskell, Logic and Automata -- Undergraduate Topics in Computer Science, Springer (2021) -- ISBN 978-3-030-76907 -- Chapter 13 : Higher and Higher module Chap13_higher_and_higher where import Chap05_lists_and_comprehensions (isPrime) import Chap12_higher_order_functions (sumSqOdds') -- Lambda expressions f :: [Int] -> Int f ns = foldr (+) 0 (map sqr (filter pos ns)) where sqr x = x * x pos x = x >= 0 f' :: [Int] -> Int f' ns = foldr (+) 0 (map (^ 2) (filter (>= 0) ns)) f'' :: [Int] -> Int f'' ns = foldr (+) 0 (map (\x -> x * x) (filter (\x -> x >= 0) ns)) -- Function composition -- The following function definition is commented out because it is already in the Prelude. -- You can hide that definition to allow it to be re-defined by putting the following at the top of this module: -- import Prelude hiding ((.)) -- (.) :: (b -> c) -> (a -> b) -> a -> c -- (f . g) x = f (g x) sumSqOdds'' :: [Int] -> Int sumSqOdds'' = foldr (+) 0 . map (^ 2) . filter odd squareNonprimes :: [Int] -> [Int] squareNonprimes = map (^ 2) . filter (not . isPrime) -- The function application operator $ -- The following function definition is commented out because it is already in the Prelude. -- You can hide that definition to allow it to be re-defined by putting the following at the top of this module: -- import Prelude hiding (($)) -- ($) :: (a -> b) -> a -> b -- f $ x = f x sumSqOdds''' :: [Int] -> Int sumSqOdds''' ns = foldr (+) 0 $ map (^ 2) $ filter odd ns -- Currying and uncurrying functions l1 = filter (\(x,y) -> x < y) (zip ["one", "two", "three", "four", "five"] ["eins", "zwei", "drei", "vier", "fünf"]) -- The following function definition is commented out because it is already in the Prelude. -- You can hide that definition to allow it to be re-defined by putting the following at the top of this module: -- import Prelude hiding (curry) -- curry :: ((a,b) -> c) -> a -> b -> c -- curry f x y = f (x,y) curry' :: ((a,b) -> c) -> a -> b -> c curry' f = \x -> \y -> f (x,y) -- The following function definition is commented out because it is already in the Prelude. -- You can hide that definition to allow it to be re-defined by putting the following at the top of this module: -- import Prelude hiding (uncurry) -- uncurry :: (a -> b -> c) -> (a,b) -> c -- uncurry f (x,y) = f x y uncurry' :: (a -> b -> c) -> (a,b) -> c uncurry' f = \(x,y) -> f x y l2 = filter (uncurry (<)) (zip ["one", "two", "three", "four", "five"] ["eins", "zwei", "drei", "vier", "fünf"]) -- Bindings and lambda expressions i1 = f 2 where f x = x + y * y where y = x + 1 i2 = (\f -> f 2) (\x -> ((\y -> x + y * y) (x + 1))) f''' x = w ^ 2 where w = x + 2 g y = f''' (y * z) where z = y + 1 i3 = g b where b = f''' 3 i4 = g b where b = f''' 3 where f''' x = w ^ 2 where w = x + 2 g y = f''' (y * z) where z = y + 1 f''' x = w ^ 2 where w = x + 2 i5 = (\b -> \g -> g b) ((\f''' -> f''' 3) (\x -> (\w -> w ^ 2) (x + 2))) (\y -> (\z -> \f''' -> f''' (y * z)) (y + 1) (\x -> (\w -> w ^ 2) (x + 2))) -- Exercise 6 -- The following function definition is commented out because it is already in the Prelude. -- You can hide that definition to allow it to be re-defined by putting the following at the top of this module: -- import Prelude hiding (unzip) -- unzip :: [(a,b)] -> ([a],[b]) -- unzip [] = ([],[]) -- unzip ((x,y):xys) = (x:xs,y:ys) -- where (xs,ys) = unzip xys -- Exercise 8 -- iter is from Exercise 1 iter :: Int -> (a -> a) -> (a -> a) iter = undefined type Church a = (a -> a) -> a -> a church :: Int -> Church a church n = iter n succ :: Church a -> Church a succ cm = \f -> \x -> f (cm f x) plus :: Church a -> Church a -> Church a plus cm cn = \f -> \x -> cm f (cn f x) unchurch :: Church Int -> Int unchurch cn = cn (+ 1) 0