# Functional Programming

## Functional Programming

Now with lists and polymorphism in our toolbox, we can finally start to look at functional programming.

In Haskell a function is a value, just like a number or a list is.
Functions can be passed as parameters to other functions. Here’s a toy
example. The function `applyTo1`

takes a function of type `Int->Int`

,
applies it to the number `1`

, and returns the result.

```
applyTo1 :: (Int -> Int) -> Int
applyTo1 f = f 1
```

Let’s define a simple function of type `Int->Int`

and see `applyTo1`

in
action.

```
addThree :: Int -> Int
addThree x = x + 3
```

```
applyTo1 addThree
==> addThree 1
==> 1 + 3
==> 4
```

Let’s go back to the type annotation for `applyTo1`

.

```
applyTo1 :: (Int -> Int) -> Int
```

The parentheses are needed because the type `Int -> Int -> Int`

would be
the type of a function taking two `Int`

arguments. More on this later.

Let’s look at a slightly more interesting example. This time we’ll
implement a polymorphic function `doTwice`

. Note how we can use it with
various types of values and functions.

```
doTwice :: (a -> a) -> a -> a
doTwice f x = f (f x)
```

```
doTwice addThree 1
==> addThree (addThree 1)
==> 7
doTwice tail "abcd"
==> tail (tail "abcd")
==> "cd"
```

```
makeCool :: String -> String
makeCool str = "WOW " ++ str ++ "!"
```

```
doTwice makeCool "Haskell"
==> "WOW WOW Haskell!!"
```

### Functional Programming on Lists

That was a bit boring. Luckily there are many useful list functions that
take functions as arguments. By the way, functions that take functions
as arguments (or return functions) are often called *higher-order
functions*.

The most famous of these list-processing higher-order functions is
`map`

. It gives you a new list by applying the given function to all
elements of a list.

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

```
map addThree [1,2,3]
==> [4,5,6]
```

The partner in crime for `map`

is `filter`

. Instead of transforming all
elements of a list, `filter`

drops some elements of a list and keeps
others. In other words, `filter`

selects the elements from a list that
fulfill a condition.

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

Here’s an example: selecting the positive elements from a list

```
positive :: Int -> Bool
positive x = x>0
```

```
filter positive [0,1,-1,3,-3]
==> [1,3]
```

Note how both the type signatures of `map`

and `filter`

use
polymorphism. They work on all kinds of lists. The type of `map`

even
uses two type parameters! Here are some examples of type inference using
`map`

and `filter`

.

```
onlyPositive xs = filter positive xs
mapBooleans f = map f [False,True]
```

```
Prelude> :t onlyPositive
onlyPositive :: [Int] -> [Int]
Prelude> :t mapBooleans
mapBooleans :: (Bool -> b) -> [b]
Prelude> :t mapBooleans not
mapBooleans not :: [Bool]
```

One more thing: remember how constructors were just functions? That means you can pass them as arguments to other functions!

```
wrapJust xs = map Just xs
```

```
Prelude> :t wrapJust
wrapJust :: [a] -> [Maybe a]
Prelude> wrapJust [1,2,3]
[Just 1,Just 2,Just 3]
```

### Examples of Functional Programming on Lists

How many “palindrome numbers” are between `1`

and `n`

?

```
-- a predicate that checks if a string is a palindrome
palindrome :: String -> Bool
palindrome str = str == reverse str
-- palindromes n takes all numbers from 1 to n, converts
-- them to strings using show, and keeps only palindromes
palindromes :: Int -> [String]
palindromes n = filter palindrome (map show [1..n])
```

```
palindrome "1331" ==> True
palindromes 150 ==>
["1","2","3","4","5","6","7","8","9",
"11","22","33","44","55","66","77","88","99",
"101","111","121","131","141"]
length (palindromes 9999) ==> 198
```

How many words in a string start with “a”? This uses the function
`words`

from the module `Data.List`

that splits a string into words.

```
countAWords :: String -> Int
countAWords str = length (filter startsWithA (words str))
where startsWithA s = head s == 'a'
```

```
countAWords "does anyone want an apple?"
==> 3
```

The function `tails`

from `Data.List`

returns the list of all suffixes
(“tails”) of a list. We can use `tails`

for many string processing
tasks. Here’s how `tails`

works:

```
tails "echo"
==> ["echo","cho","ho","o",""]
```

Here’s an example where we find what characters come after a given
character in a string. First of all, we use `tails`

, `map`

and `take`

to
get all substrings of a certain length:

```
substringsOfLength :: Int -> String -> [String]
substringsOfLength n string = map shorten (tails string)
where shorten s = take n s
```

```
substringsOfLength 3 "hello"
==> ["hel","ell","llo","lo","o",""]
```

There’s some shorter substrings left at the end (can you see why?), but
they’re fine for our purposes right now. Now that we have
`substringsOfLength`

, we can implement the function `whatFollows c k s`

that finds all the occurrences of the character `c`

in the string `s`

,
and outputs the `k`

letters that come after these occurrences.

```
whatFollows :: Char -> Int -> String -> [String]
whatFollows c k string =
map tail (filter match (substringsOfLength (k+1) string))
where match sub = take 1 sub == [c]
```

```
whatFollows 'a' 2 "abracadabra"
==> ["br","ca","da","br",""]
```

## Partial Application

When using higher-order functions you can find yourself defining lots of
small helper functions, like `addThree`

or `shorten`

in the previous
examples. This is a bit of a chore in the long run, but luckily
Haskell’s functions behave a bit weirdly…

Let’s start in GHCi:

```
Prelude> let add a b = a+b
Prelude> add 1 5
6
Prelude> let addThree = add 3
Prelude> addThree 2
5
```

So, we’ve defined `add`

, a function of two arguments, and only given it
one argument. The result is not a type error but a new function. The new
function just stores (or remembers) the given argument, waits for
another argument, and then gives both to `add`

.

```
Prelude> map addThree [1,2,3]
[4,5,6]
Prelude> map (add 3) [1,2,3]
[4,5,6]
```

Here we can see that we don’t even need to give a name to the function
returned by `add 3`

. We can just use it anywhere where a function of one
argument is expected.

This is called *partial application*. All functions in Haskell behave
like this. Let’s have a closer look. Here’s a function that takes many
arguments.

```
between :: Integer -> Integer -> Integer -> Bool
between lo high x = x < high && x > lo
```

```
Prelude> between 3 7 5
True
Prelude> between 3 6 8
False
```

We can give `between`

less arguments and get back new functions, just
like we saw with `add`

:

```
Prelude> (between 1 5) 2
True
Prelude> let f = between 1 5 in f 2
True
Prelude> map (between 1 3) [1,2,3]
[False,True,False]
```

Look at the types of partially applying `between`

. They behave neatly,
with arguments disappearing one by one from the type as values are added
to the expression.

```
Prelude> :t between
between :: Integer -> Integer -> Integer -> Bool
Prelude> :t between 1
between 1 :: Integer -> Integer -> Bool
Prelude> :t between 1 2
between 1 2 :: Integer -> Bool
Prelude> :t between 1 2 3
between 1 2 3 :: Bool
```

Actually, when we write a type like
`Integer -> Integer -> Integer -> Bool`

, it means
`Integer -> (Integer -> (Integer -> Bool))`

. That is, a multi-argument
function is just a function that returns a function. Similarly, an
expression like `between 1 2 3`

is the same as `((between 1) 2) 3`

, so
passing multiple arguments to a function happens via multiple
single-argument calls. Representing multi-argument functions like this
is called *currying* (after the logician Haskell Curry). Currying is
what makes partial application possible.

Here’s another example of using partial application with `map`

:

```
map (drop 1) ["Hello","World!"]
==> ["ello","orld!"]
```

In addition to normal functions, partial application also works with
operators. With operators you can choose whether you apply the left or
the right argument. (Partially applied operators are also called
*sections* or *operator sections*). Some examples:

```
Prelude> map (*2) [1,2,3]
[2,4,6]
Prelude> map (2*) [1,2,3]
[2,4,6]
Prelude> map (1/) [1,2,3,4,5]
[1.0,0.5,0.3333333333333333,0.25,0.2]
```

## Prefix and Infix Notations

Normal Haskell operators are applied with *prefix notation*, which is
just a fancy way to say that the function name comes before the
arguments. In contrast, operators are applied with *infix notation* –
the name of the function comes between the arguments.

An infix operator can be converted into a prefix function by adding parentheses around it. For instance,

```
(+) 1 2 ==> 1 + 2 ==> 3
```

This is useful especially when an operator needs to be passed as an argument to another function.

As an example, the function `zipWith`

takes two lists, a binary
function, and joins the lists using the function. We can use
`zipWith (+)`

to sum two lists, element-by-element:

```
Prelude> :t zipWith
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Prelude> zipWith (+) [0,2,5] [1,3,3]
[1,5,8]
```

Without the ability to turn an operator into a function, we’d have to
use a helper function – such as `add`

above.

Note that omitting the parentheses leads into a type error:

```
Prelude> zipWith + [0,2,5,3] [1,3,3]
<interactive>:1:11: error:
• Couldn't match expected type
‘[Integer] -> (a -> b -> c) -> [a] -> [b] -> [c]’
with actual type ‘[Integer]’
• The function ‘[0, 2, 5, 3]’ is applied to one argument,
but its type ‘[Integer]’ has none
In the second argument of ‘(+)’,
namely ‘[0, 2, 5, 3] [1, 3, 3]’
In the expression: zipWith + [0, 2, 5, 3] [1, 3, 3]
• Relevant bindings include
it :: (a -> b -> c) -> [a] -> [b] -> [c]
(bound at <interactive>:1:1)
```

The reason for this weird-looking error is that GHCi got confused and
thought that we were somehow trying to add `zipWith`

and
`[0,2,5,3] [1,3,3]`

together. Logically, it deduced that `[0,2,5,3]`

must be a function since it’s being applied to `[1,3,3]`

(remember that
functions bind tighter than operators).

Unfortunately, error messages can sometimes be obscure, since the compiler cannot always know the “real” cause of the error (which is in this case was omitting the parentheses). Weird error messages are frustrating, but only the programmer knows what was the original intent behind the code.

Another nice feature of Haskell is the syntax for applying a binary function as if it was an infix operator, by surrounding it with backticks (`). For example:

```
6 `div` 2 ==> div 6 2 ==> 3
(+1) `map` [1,2,3] ==> map (+1) [1,2,3] ==> [2,3,4]
```

## Lambdas

The last spanner we need in our functional programming toolbox is λ
(lambda). Lambda expressions are *anonymous functions*. Consider a
situation where you need a function only once, for example in an
expression like

```
let big x = x>7 in filter big [1,10,100]
```

A lambda expression allows us to write this directly, without defining a
name (`big`

) for the helper function:

```
filter (\x -> x>7) [1,10,100]
```

Here are some more examples in GHCi:

```
Prelude> (\x -> x*x) 3
9
Prelude> (\x -> reverse x == x) "ABBA"
True
Prelude> filter (\x -> reverse x == x) ["ABBA","ACDC","otto","lothar","anna"]
["ABBA","otto","anna"]
Prelude> (\x y -> x^2+y^2) 2 3 -- multiple arguments
13
```

The Haskell syntax for lambdas is a bit surprising. The backslash
character (`\`

) stands for the greek letter lambda (λ). The Haskell
expression `\x -> x+1`

is trying to mimic the mathematical notation *λx.
x+1*. Other languages use syntax like `x => x+1`

(JavaScript) or
`lambda x: x+1`

(Python).

**Note!** You never *need* to use a lambda expression. You can always
instead define the function normally using `let`

or `where`

.

By the way, lambda expressions are quite powerful constructs which have a deep theory of their own, known as Lambda calculus. Some even consider purely functional programming languages such as Haskell to be typed extensions of Lambda calculus with extra syntax.

## Sidenote: The `.`

and `$`

Operators

The two most common operators in Haskell codebases are probably `.`

and
`$`

. They are useful when writing code that uses higher-order functions.
The first of these, the `.`

operator, is the *function composition*
operator. Here’s its type

```
(.) :: (b -> c) -> (a -> b) -> a -> c
```

And here’s what it does

```
(f.g) x ==> f (g x)
```

You can use function composition to build functions out of other functions, without mentioning any arguments. For example:

```
double x = 2*x
quadruple = double . double -- computes 2*(2*x) == 4*x
f = quadruple . (+1) -- computes 4*(x+1)
g = (+1) . quadruple -- computes 4*x+1
third = head . tail . tail -- fetches the third element
-- of a list
```

We can also reimplement `doTwice`

using `(.)`

. Note how we can use
`doTwice`

both as applied only to a function, or as applied to a
function and a value.

```
doTwice :: (a -> a) -> a -> a
doTwice f = f . f
```

```
let ttail = doTwice tail
in ttail [1,2,3,4]
==> [3,4]
(doTwice tail) [1,2,3,4] ==> [3,4]
doTwice tail [1,2,3,4] ==> [3,4]
```

Often function composition is not used when defining a new function, but instead to avoid defining a helper function. For instance, consider the difference between these two expressions:

```
let notEmpty x = not (null x)
in filter notEmpty [[1,2,3],[],[4]]
==> [[1,2,3],[4]]
```

```
filter (not . null) [[1,2,3],[],[4]]
==> [[1,2,3],[4]]
```

The other operator, `$`

is more subtle. Let’s look at its type.

```
($) :: (a -> b) -> a -> b
```

It takes a function of type `a -> b`

and a value of type `a`

, and
returns a value of type `b`

. In other words, it’s a function application
operator. The expression `f $ x`

is the same as `f x`

. This seems pretty
useless, but it means that the `$`

operator can be used to eliminate
parentheses! These expressions are the same:

```
head (reverse "abcd")
head $ reverse "abcd"
```

This isn’t that impressive when it’s used to eliminate one pair of
parentheses, but together `.`

and `$`

can eliminate lots of them! For
example, we can rewrite

```
reverse (map head (map reverse (["Haskell","pro"] ++ ["dodo","lyric"])))
```

as

```
(reverse . map head . map reverse) (["Haskell","pro"] ++ ["dodo","lyric"])
```

and then

```
reverse . map head . map reverse $ ["Haskell","pro"] ++ ["dodo","lyric"]
```

Sometimes the operators `.`

and `$`

are useful as functions in their own
right. For example, a list of functions can be applied to an argument
using map and a section of `$`

:

```
map ($"string") [reverse, take 2, drop 2]
==> [reverse $ "string", take 2 $ "string",
drop 2 $ "string"]
==> [reverse "string", take 2 "string", drop 2 "string"]
==> ["gnirts", "st", "ring"]
```

If this seems complicated, don’t worry. You don’t need to use `.`

and
`$`

in your own code until you’re comfortable with them. However, you’ll
bump into `.`

and `$`

when reading Haskell examples and code on the
internet, so it’s good to know about them. This
article might also help.

## Example: Rewriting `whatFollows`

Now, let’s rewrite the `whatFollows`

example from earlier using the
tools we just saw. Here’s the original version:

```
substringsOfLength :: Int -> String -> [String]
substringsOfLength n str = map shorten (tails str)
where shorten s = take n s
whatFollows :: Char -> Int -> String -> [String]
whatFollows c k str =
map tail (filter match (substringsOfLength (k+1) str))
where match sub = take 1 sub == [c]
```

To get started, let’s get rid of the helper function
`substringsOfLength`

and move all the code to `whatFollows`

:

```
whatFollows c k str =
map tail (filter match (map shorten (tails str)))
where shorten s = take (k+1) s
match sub = take 1 sub == [c]
```

Now let’s use partial application instead of defining `shorten`

:

```
whatFollows c k str =
map tail (filter match (map (take (k+1)) (tails str)))
where match sub = take 1 sub == [c]
```

Let’s use `.`

and `$`

to eliminate some of those parentheses:

```
whatFollows c k str =
map tail . filter match . map (take (k+1)) $ tails str
where match sub = take 1 sub == [c]
```

We can also replace `match`

with a lambda:

```
whatFollows c k string =
map tail . filter (\sub -> take 1 sub == [c])
. map (take (k+1)) $ tails string
```

Finally, we don’t need to mention the `string`

parameter at all, since
we can just express `whatFollows`

as a composition of `map`

, `filter`

,
`map`

and `tails`

:

```
whatFollows c k =
map tail . filter (\sub -> take 1 sub == [c])
. map (take (k+1))
. tails
```

We can even go a bit further by rewriting the lambda using an operator section

```
\sub -> take 1 sub == [c]
=== \sub -> (==[c]) (take 1 sub)
=== \sub -> (==[c]) ((take 1) sub)
=== \sub -> ((==[c]) . (take 1)) sub
=== ((==[c]) . (take 1))
=== ((==[c]) . take 1)
```

Now what we have left is:

```
whatFollows c k = map tail . filter ((==[c]) . take 1)
. map (take (k+1))
. tails
```

This is a somewhat extreme version of the function, but when used in moderation the techniques shown here can make code easier to read.

## More Functional List Wrangling Examples

Here are some more examples of functional programming with lists. Let’s start by introducing a couple of new list functions:

```
-- take elements from a list as long as they satisfy
-- a predicate
takeWhile :: (a -> Bool) -> [a] -> [a]
-- drop elements from a list as long as they satisfy
-- a predicate
dropWhile :: (a -> Bool) -> [a] -> [a]
```

```
takeWhile even [2,4,1,2,3] ==> [2,4]
dropWhile even [2,4,1,2,3] ==> [1,2,3]
```

There’s also the function `elem`

, which can be used to check if a list
contains an element:

```
elem 3 [1,2,3] ==> True
elem 4 [1,2,3] ==> False
```

Using these, we can implement a function `findSubstring`

that finds the
earliest and longest substring in a string that consist only of the
given characters.

```
findSubstring :: String -> String -> String
findSubstring chars = takeWhile (\x -> elem x chars)
. dropWhile (\x -> not $ elem x chars)
```

```
findSubstring "a" "bbaabaaaab" ==> "aa"
findSubstring "abcd" "xxxyyyzabaaxxabcd" ==> "abaa"
```

The function `zipWith`

lets you combine two lists element-by-element:

```
zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
```

```
zipWith (++) ["John","Mary"] ["Smith","Cooper"]
==> ["JohnSmith","MaryCooper"]
zipWith take [4,3] ["Hello","Warden"]
==> ["Hell","War"]
```

Sometimes with higher-order functions it’s useful to have a function
that does nothing. The function `id :: a -> a`

is the identity function
and just returns its argument.

```
id 3 ==> 3
map id [1,2,3] ==> [1,2,3]
```

This seems a bit useless, but you can use it for example with `filter`

or `dropWhile`

:

```
filter id [True,False,True,True]
==> [True,True,True]
dropWhile id [True,True,False,True,False]
==> [False,True,False]
```

Another very simple but sometimes crucial function is the constant
function, `const :: a -> b -> a`

. It always returns its first argument:

```
const 3 True ==> 3
const 3 0 ==> 3
```

When partially applied it can be used when you need a function that always returns the same value:

```
map (const 5) [1,2,3,4]
==> [5,5,5,5]
filter (const True) [1,2,3,4]
==> [1,2,3,4]
```

## Lists and Recursion

Here’s a new operator, `:`

```
Prelude> 1:[]
[1]
Prelude> 1:[2,3]
[1,2,3]
Prelude> tail (1:[2,3])
[2,3]
Prelude> head (1:[2,3])
1
Prelude> :t (:)
(:) :: a -> [a] -> [a]
```

The `:`

operator builds a list out of a head and a tail. In other words,
`x : xs`

is the same as `[x] ++ xs`

. Why do we need an operator for
this?

Actually, `:`

is the *constructor* for lists: it returns a new linked
list node. The other list constructor is `[]`

, the empty list. All lists
are built using `:`

and `[]`

. The familiar `[x,y,z]`

syntax is actually
just a nicer way to write `x:y:z:[]`

, or even more explicitly,
`x:(y:(z:[]))`

. In fact `(++)`

is defined in terms of `:`

and recursion
in the standard library.

Here’s a picture of how `[1,2,3]`

is structured in memory:

### Building a List

Using `:`

we can define recursive functions that build lists. For
example here’s a function that builds lists like `[3,2,1]`

:

```
descend 0 = []
descend n = n : descend (n-1)
```

```
descend 4 ==> [4,3,2,1]
```

Here’s a function that builds a list by iterating a function `n`

times:

```
iterate f 0 x = [x]
iterate f n x = x : iterate f (n-1) (f x)
```

```
iterate (*2) 4 3 ==> [3,6,12,24,48]
let xs = "terve"
in iterate tail (length xs) xs
==> ["terve","erve","rve","ve","e",""]
```

Here’s a more complicated example: splitting a string into pieces at a given character:

```
split :: Char -> String -> [String]
split c [] = []
split c xs = start : split c (drop 1 rest)
where start = takeWhile (/=c) xs
rest = dropWhile (/=c) xs
```

```
split 'x' "fooxxbarxquux" ==> ["foo","","bar","quu"]
```

### Pattern Matching for Lists

Last lecture, it was said that constructors are things that can be
pattern matched on. Above, it was divulged that the constructors for the
list type are `:`

and `[]`

. We can put one and one together and guess
that we can pattern match on `:`

and `[]`

. This is true! Here’s how you
can define your own versions of `head`

and `tail`

using pattern
matching:

```
myhead :: [Int] -> Int
myhead [] = -1
myhead (first:rest) = first
mytail :: [Int] -> [Int]
mytail [] = []
mytail (first:rest) = rest
```

You can *nest* patterns. That is, you can pattern match more than one
element from the start of a list. In this example, we use the pattern
`(a:b:_)`

which is the same as `(a:(b:_))`

:

```
sumFirstTwo :: [Integer] -> Integer
-- this equation gets used for lists of length at least two
sumFirstTwo (a:b:_) = a+b
-- this equation gets used for all other lists
-- (i.e. lists of length 0 or 1)
sumFirstTwo _ = 0
```

```
sumFirstTwo [1] ==> 0
sumFirstTwo [1,2] ==> 3
sumFirstTwo [1,2,4] ==> 3
```

Here’s an example that uses many different list patterns:

```
describeList :: [Int] -> String
describeList [] = "an empty list"
describeList (x:[]) = "a list with one element"
describeList (x:y:[]) = "a list with two elements"
describeList (x:y:z:xs) =
"a list with at least three elements"
```

```
describeList [1,3]
==> "a list with two elements"
describeList [1,2,3,4,5]
==> "a list with at least three elements"
```

List patterns that end with `:[]`

can be typed out as list literals.
That is, just like `[1,2,3]`

is the same value as `1:2:3:[]`

, the
pattern `[x,y]`

is the same as the pattern `x:y:[]`

. Let’s rewrite that
previous example.

```
describeList :: [Int] -> String
describeList [] = "an empty list"
describeList [x] = "a list with exactly one element"
describeList [x,y] = "a list with exactly two elements"
describeList (x:y:z:xs) =
"a list with at least three elements"
```

Another way we can nest patterns is pattern matching on the head while
pattern matching on a list. For example this function checks if a list
starts with `0`

:

```
startsWithZero :: [Integer] -> Bool
startsWithZero (0:xs) = True
startsWithZero (x:xs) = False
startsWithZero [] = False
```

### Consuming a List

Using pattern matching and recursion, we can recursively process a whole list. Here’s how you sum all the numbers in a list:

```
sumNumbers :: [Int] -> Int
sumNumbers [] = 0
sumNumbers (x:xs) = x + sumNumbers xs
```

Here’s how you compute the largest number in a list, this time using a helper function.

```
myMaximum :: [Int] -> Int
myMaximum [] = 0 -- actually this should be an error...
myMaximum (x:xs) = go x xs
where go biggest [] = biggest
go biggest (x:xs) = go (max biggest x) xs
```

**Note:**, `go`

is just a cute name for the helper function here. It’s
not special syntax.

It’s often convenient to use nested patterns while consuming a list.
Here’s an example that counts how many `Nothing`

values occur in a list
of `Maybe`

s:

```
countNothings :: [Maybe a] -> Int
countNothings [] = 0
countNothings (Nothing : xs) = 1 + countNothings xs
countNothings (Just _ : xs) = countNothings xs
```

```
countNothings [Nothing,Just 1,Nothing] ==> 2
```

### Building and Consuming a List

Now that we can build and consume lists, let’s do both of them at the same time. This function doubles all elements in a list.

```
doubleList :: [Int] -> [Int]
doubleList [] = []
doubleList (x:xs) = 2*x : doubleList xs
```

It evaluates like this:

```
doubleList [1,2,3]
=== doubleList (1:(2:(3:[])))
==> 2*1 : doubleList (2:(3:[]))
==> 2*1 : (2*2 : doubleList (3:[]))
==> 2*1 : (2*2 : (2*3 : doubleList []))
==> 2*1 : (2*2 : (2*3 : []))
=== [2*1, 2*2, 2*3]
==> [2,4,6]
```

Once you know pattern matching for lists, it’s straightforward to define
`map`

and `filter`

. Actually, let’s just look at the GHC standard
library implementations. Here’s
map:

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

and here’s filter:

```
filter :: (a -> Bool) -> [a] -> [a]
filter _pred [] = []
filter pred (x:xs)
| pred x = x : filter pred xs
| otherwise = filter pred xs
```

**Note!** Naming the argument `_pred`

is a way to tell the reader of
the code that this argument is unused. It could have been just `_`

as
well.

### Tail Recursion and Lists

When a recursive function evaluates to a new call to that same function
with different arguments, it is called *tail-recursive*. (The recursive
call is said to be in *tail position*.) This is the type of recursion
that corresponds to an imperative loop. We’ve already seen many examples
of tail-recursive functions, but we haven’t really contrasted the two
ways for writing the same function. This is `sumNumbers`

from earlier in
this lecture:

```
sumNumbers :: [Int] -> Int
sumNumbers [] = 0
sumNumbers (x:xs) = x + sumNumbers xs
```

In the second equation the function `+`

is at the top level, i.e. in
tail position. The recursive call to `sumNumbers`

is an argument of `+`

.
This is `sumNumbers`

written using a tail recursive helper function:

```
sumNumbers :: [Int] -> Int
sumNumbers xs = go 0 xs
where go sum [] = sum
go sum (x:xs) = go (sum+x) xs
```

Note the second equation of `go`

: it has the recursive call to `go`

at
the top level, i.e. in tail position. The `+`

is now in an argument to
`go`

.

For a function like `sumNumbers`

that produces a single value (a
number), it doesn’t really matter which form of recursion you choose.
The non-tail-recursive function is easier to read, while the
tail-recursive one can be easier to come up with. You can try writing a
function both ways. The tail-recursive form might be more efficient, but
that depends on many details.

However, when you’re returning a list there is a big difference between
these two forms. Consider the function `doubleList`

from earlier. Here
it is again, implemented first directly, and then via a tail-recursive
helper function.

```
doubleList :: [Int] -> [Int]
doubleList [] = []
doubleList (x:xs) = 2*x : doubleList xs
```

```
doubleList :: [Int] -> [Int]
doubleList xs = go [] xs
where go result [] = result
go result (x:xs) = go (result++[2*x]) xs
```

Here the direct version is much more efficient. The `(:)`

operator works
in constant time, whereas the `(++)`

operator needs to walk the whole
list, needing linear time. Thus the direct version uses linear time
(*O(n)*) with respect to the length of the list, while the
tail-recursive version is quadratic (*O(n²)*)!

One might be tempted to fix this by using `(:)`

in the tail-recursive
version, but then the list would get generated in the reverse order.
This could be fixed with an application of `reverse`

, but that would
make the resulting function quite complicated.

There is another reason to prefer the direct version: laziness. For now it’s enough for you to know that **the direct way of generating a list is simpler,
more efficient and more idiomatic**. You should try to practice it in
the exercises. Check out the standard library implementations of `map`

and `filter`

above, even they produce the list directly without tail
recursion!

## Something Fun: List Comprehensions

Haskell has *list comprehensions*, a nice syntax for defining lists that
combines the power of `map`

and `filter`

. You might be familiar with
Python’s list comprehensions already. Haskell’s work pretty much the
same way, but their syntax is a bit different.

Mapping:

```
[2*i | i<-[1,2,3]]
==> [2,4,6]
```

Filtering:

```
[i | i <- [1..7], even i]
==> [2,4,6]
```

In general, these two forms are equivalent:

```
[f x | x <- lis, p x]
map f (filter p lis)
```

List comprehensions can do even more. You can iterate over multiple lists:

```
[ x ++ " " ++ y | x <- ["A", "B"], y <- ["C","D"] ]
==> ["AC","AD","BC","BD"]
```

You can make local definitions:

```
[ reversed | word <- ["this","is","a","string"],
let reversed = reverse word ]
==> ["siht","si","a","gnirts"]
```

You can even do pattern matching in list comprehensions!

```
firstLetters string = [ char | (char:_) <- words string ]
```

```
firstLetters "Hello World!"
==> "HW"
```

## Something Fun: Custom Operators

In Haskell an *operator* is anything built from the characters
`!#$%&*+./<=>?@\^|-~`

. Operators can be defined just like functions
(note the slightly different type annotation):

```
(<+>) :: [Int] -> [Int] -> [Int]
xs <+> ys = zipWith (+) xs ys
```

```
(+++) :: String -> String -> String
a +++ b = a ++ " " ++ b
```

## Self Checks

### Check 1

What’s the type of this function?

```
both p q x = p x && q x
```

`a -> Bool -> a -> Bool -> a -> Bool`

`(a -> Bool) -> (a -> Bool) -> a -> Bool`

`(a -> Bool) -> (b -> Bool) -> c -> Bool`

### Check 2

What’s the type of this function?

```
applyInOut f g x = f (g (f x))`
```

`(a -> b) -> (b -> a) -> a -> b`

`(a -> b) -> (b -> c) -> a -> c`

`(a -> a) -> (a -> a) -> a -> a`

### Check 3

Which one of the following functions adds its first argument to the second?

`f x x = x + x`

`f x = \y -> x + y`

`f = \x y -> x + x`

### Check 4

Which one of these functions does not satisfy `f 1 ==> 1`

?

`f x = (\y -> y) x`

`f x = \y -> y`

`f x = (\y -> x) x`

### Check 5

Which one of the following functions is correctly typed?

`f x y = not x; f :: (Bool -> Bool) -> Bool`

`f x = x ++ "a"; f :: Char -> String`

`f x = 'a' : x; f :: String -> String`

### Check 6

How many arguments does `drop 2`

take?

- Zero
- One
- Two

### Check 7

What does this function do? `f (_:x:_) = x`

- Returns the first element of a list
- Returns an arbitrary element of a list
- Returns all except the first and last elements of a list
- Returns the second element of a list

### Check 8

What is the result of the following expression?

```
reverse $ take 5 . tail $ "This is a test"`
```

`"i sih"`

`"set a"`

- A type error

### Check 9

If `f :: a -> b`

, then what is the type of `map (.f)`

?

`[b -> c] -> [a -> c]`

`[c -> a] -> [c -> b]`

`(b -> c) -> [a -> c]`

`[a] -> [b]`

### Check 10

What is the type of the leftmost `id`

in `id id`

?

- unspecified
`a`

`a -> a`

`(a -> a) -> (a -> a)`

### Check 11

What is the type of `const const`

?

- unspecified
`(c -> a -> b) -> a`

`c -> (a -> b -> a)`

`a -> b -> c -> a`

#### Acknowledgment:

This reading was originally written by **Joel Kaasinen** and
**John Lång** in their
open source textbook.
The book is licensed under the
Creative Commons Attribution-ShareAlike 4.0 International License,
which allows users to copy, modify, and distribute the book.

This reading was modified by Titus H. Klinge in 2021 and presented above under the same license in order to better serve the students of this course.