80 likes | 252 Views
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
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)]