Search⌘ K
AI Features

Higher-Order Functions on Lists I: Map and Filter

Explore how to simplify list processing in Haskell by using higher-order functions like map and filter. Understand patterns for transforming and filtering list elements without explicit recursion, and apply these techniques to practical examples such as counting word frequencies.

In the previous lessons, we learned how to write recursive functions on lists. There are a few recursion patterns that occur again and again. They can be abstracted in higher-order functions on lists. This allows us to write expressive list functions without worrying too much about implementing explicit recursion.

Map

The first recursion pattern we will look at is transforming list elements. For example, we might want to round each double in a list to its nearest integer.

Haskell
roundList :: [Double] -> [Int]
roundList [] = []
roundList (x:xs) = round x : roundList xs
main = print (roundList [1.3, 3.7, 4.0484])

Or we might want to lowercase each character in a string.

Haskell
import Data.Char
lowerString :: [Char] -> [Char]
lowerString [] = []
lowerString (x:xs) = toLower x : lowerString xs
main = print (lowerString "HELLO, HOW ARE YOU?")

Both specific functions follow the same general pattern:

  1. They act on a list with some element type a and return another list with some element type b.
  2. They apply a function of type a -> b (e.g. round, toLower) element wise to the list.

This pattern is captured by the general function map, available in the Haskell Prelude. Its implementation is

map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs

Using the higher-order function map we can write more concise versions of roundList ...