Working with functions
1 2 3 4 5 6 7
sum :: [Int] -> Int sum  = 0 sum (x:xs) = x + sum xs product :: [Int] -> Int product  = 1 product (x:xs) = x * product xs
Note the similarities in the two examples. Both functions combine the elements of the list with a binary operation. We can abstract out the similarities into a higher-order function.
We abstract out the binary operation as well as the default value into a function called aggregate, shown below:
1 2 3 4
aggregate :: (Int -> Int -> Int) -> Int -> [Int] -> Int aggregate combine default  = default aggregate combine default (x:xs) = combine x (aggregate combine default xs)
Now we can redefine sum and product as:
sum = aggregate (+) 0 product = aggregate (*) 1
Higher order functions allow us to abstract out common patterns and allow us to define powerful, re-usable functions.
The aggregate function is still highly specialized. The Eta standard library provides many general, useful, higher-order functions:
map :: (a -> b) -> [a] -> [b] map (* 2) [1..5] == [2,4,6,8,10]
map transforms a list by taking a function that converts each element. Note that map preserves the original structure (doesn't delete or add elements), and each element is operated on independently.
filter :: (a -> Bool) -> [a] -> [a] filter (> 3) [1..5] == [4,5]
filter takes a list and generates a new list keeping the elements that satisfy the predicate that is supplied.