Online Book Reader

Home Category

Learn You a Haskell for Great Good! - Miran Lipovaca [30]

By Root 427 0

[0,0,0,0,1]

ghci> zipWith (flip' div) [2,2..] [10,8,6,4,2]

[5,4,3,2,1]

If we flip' the zip function, we get a function that is like zip, except that the items from the first list are placed into the second components of the tuples and vice versa. The flip' div function takes its second parameter and divides that by its first, so when the numbers 2 and 10 are passed to flip' div, the result is the same as using div 10 2.

The Functional Programmer's Toolbox

As functional programmers, we seldom want to operate on just one value. We usually want to take a bunch of numbers, letters, or some other type of data, and transform the set to produce our results. In this section, we’ll look at some useful functions that can help us work with multiple values.

The map Function


The map function takes a function and a list, and applies that function to every element in the list, producing a new list. Here is its definition:

map :: (a -> b) -> [a] -> [b]

map _ [] = []

map f (x:xs) = f x : map f xs

The type signature says that map takes a function from a to b and a list of a values, and returns a list of b values.

map is a versatile higher-order function that can be used in many different ways. Here it is in action:

ghci> map (+3) [1,5,3,1,6]

[4,8,6,4,9]

ghci> map (++ "!") ["BIFF", "BANG", "POW"]

["BIFF!","BANG!","POW!"]

ghci> map (replicate 3) [3..6]

[[3,3,3],[4,4,4],[5,5,5],[6,6,6]]

ghci> map (map (^2)) [[1,2],[3,4,5,6],[7,8]]

[[1,4],[9,16,25,36],[49,64]]

ghci> map fst [(1,2),(3,5),(6,3),(2,6),(2,5)]

[1,3,6,2,2]

You’ve probably noticed that each of these examples could also be achieved with a list comprehension. For instance, map (+3) [1,5,3,1,6] is technically the same as [x+3 | x <- [1,5,3,1,6]]. However, using the map function tends to make your code much more readable, especially once you start dealing with maps of maps.

The filter Function


The filter function takes a predicate and a list, and returns the list of elements that satisfy that predicate. (Remember that a predicate is a function that tells whether something is true or false; that is, a function that returns a Boolean value.) The type signature and implementation look like this:

filter :: (a -> Bool) -> [a] -> [a]

filter _ [] = []

filter p (x:xs)

| p x = x : filter p xs

| otherwise = filter p xs

If p x evaluates to True, the element is included in the new list. If it doesn’t evaluate to True, it isn’t included in the new list.

Here are some filter examples:

ghci> filter (>3) [1,5,3,2,1,6,4,3,2,1]

[5,6,4]

ghci> filter (==3) [1,2,3,4,5]

[3]

ghci> filter even [1..10]

[2,4,6,8,10]

ghci> let notNull x = not (null x) in filter notNull

[[1,2,3],[],[3,4,5],[2,2],[],[],[]]

[[1,2,3],[3,4,5],[2,2]]

ghci> filter (`elem` ['a'..'z']) "u LaUgH aT mE BeCaUsE I aM diFfeRent"

"uagameasadifeent"

ghci> filter (`elem` ['A'..'Z']) "i LAuGh at you bEcause u R all the same"

"LAGER"

As with the map function, all of these examples could also be achieved by using comprehensions and predicates. There’s no set rule for when to use map and filter versus using list comprehensions. You just need to decide what’s more readable depending on the code and the context.

The filter equivalent of applying several predicates in a list comprehension is either filtering something several times or joining the predicates with the logical && function. Here’s an example:

ghci> filter (<15) (filter even [1..20])

[2,4,6,8,10,12,14]

In this example, we take the list [1..20] and filter it so that only even numbers remain. Then we pass that list to filter (<15) to get rid of numbers 15 and up. Here’s the list comprehension version:

ghci> [x | x <- [1..20], x < 15, even x]

[2,4,6,8,10,12,14]

We use a list comprehension where we draw from the list [1..20], and then say what conditions need to hold for a number to be in the resulting list.

Remember our quicksort function from Chapter 4? We used list comprehensions to filter out the list elements that were less than (or equal to) or greater than the pivot. We can achieve the same functionality in a more readable

Return Main Page Previous Page Next Page

®Online Book Reader