80 likes | 89 Views
Learn about the different patterns of computation over lists, including mapping, filtering, and folding. Explore examples and generalizations of these functions, as well as concepts like function composition and lambda notation.
E N D
Patterns of computation over lists • Applying to all – mapping map :: (a -> b) -> [a] -> [b] map f xs = [f x | x <- xs] • Selecting elements – filtering filter :: (a -> Bool) -> [a] -> [a] filter p xs = [x | x<- xs, p x] • Combing the items – folding foldr :: (a -> b -> b) -> b -> [a] -> b foldr f s [] = s foldr f s (x:xs) = f x (foldr f s xs)
Folding • Binary (associative) operation op on a type a with neutral element e (Examples: (+,0), (*,1), (++,[]) , (&&,True), (||,False), (.,id) ) foldr op e [a0,a1,…,an-1,an] ( or foldl ) = a0 `op` a1 `op` … `op` an-1 `op` an foldr op e [] = e • Binary (associative) operation op on a type a (without a neutral element) (Examples: max, min, lcm, gcd ) foldr1 op [a0,a1,…,an-1,an] ( or foldl ) = a0 `op` a1 `op` … `op` an-1 `op` an foldr1 op [] is not defined (causes an error) If op is not associative the foldl and foldr versions may result in different functions.
Folding • Binary function with arguments from different types Examples: reverse :: [a] -> [a] reverse = foldl (flip (:)) [] sort :: Ord a => [a] -> [a] sort = foldr insert [] Notice that foldr (flip (:)) [] and foldl insert [] don’t work.
Generalization Consider the following function: getWord :: String -> String getWord [] = [] getWord (x:xs) | isSpace x = [] | otherwise = x : getWord xs We can generalize this function to have a test – or property – as a parameter. getUntil :: (a -> Bool) -> [a] -> [a] getUntil … getWord = getUntil isSpace
Functions as values • Function composition (.) :: (b -> c) -> (a -> b) -> (a -> c) (f . g) x = f (g x) infixl 9 >.> (>.>) :: (a -> b) -> (b -> c) -> (a -> c) g >.> f = f . g
Lambda notation • Instead of naming and defining a function, we can write it down directly. \n -> 2*n • The following definitions of f are equivalent: f x y = result f = \x y -> result • Example: multiples :: Int -> [Int] -> [Int] multiples n = filter (\x -> x `mod` n == 0)
Example: creating an index Example: Input: ”cathedral doggerel cathedral\nbattery doggerel cathedral\n cathedral” Output: battery 2 cathedral 1, 2, 3 doggerel 1, 2 makeIndex :: Doc -> [([Int],Word)] type Doc = String type Line = String type Word = String
Example (cont’d) makeIndex = lines >.> -- Doc -> [Line] numLines >.> -- [Line] -> [(Int,Line)] allNumWords >.> -- [(Int,Line)] -> [(Int,Word)] sortLs >.> -- [(Int,Word)] -> [(Int,Word)] makeLists >.> -- [(Int,Word)] -> [([Int],Word)] amalgamate >.> -- [([Int],Word)] -> [([Int],Word)] shorten -- [([Int],Word)] -> [([Int],Word)]