```
module HigherOrder where
import Prelude hiding ((++))
```

Polymorphic Functions (#polymorphism)

Polymorphic Data (#polymorphic-data-structures)

Bottling Computation Patterns (#bottling-computation-patterns)

Many functions are **oblivious** to the type of their arguments

`doTwice f x = f (f x)`

Works on **many** kinds of values

```
ghci> :type doTwice
doTwice :: (a -> a) -> a -> a
```

`a`

**takes**function`f :: a -> a`

**takes**value`x`

:: a`**returns**an`a`

Many functions are **oblivious** to the type of their arguments

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

`Int`

values```
ghci> doTwice (+1) 0
2
```

Type parameter `a`

is **instantiated** as `Int`

Many functions are **oblivious** to the type of their arguments

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

`String`

values```
ghci> doTwice (++ "I don't care! ") "Isn't this neat ?"
"Isn't this neat ? I don't care! I don't care! "
```

Type parameter `a`

is **instantiated** as `String`

`doTwice`

is PolymorphicWorks on **many** kinds of values

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

- Doing twice is
**independent of**operation and data - Don't need
**separate**versions for`Int`

,`String`

...

Works on **many** kinds of values

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

**Reuse** same `doTwice`

across different **operators** and **data**

... comes great responsibility!

```
ghci> (10 <) 12
True
```

**Quiz:** What is the value of?

`ghci> doTwice (10 <) 100`

... comes great responsibility!

`ghci> doTwice (10 <) 100`

```
doTwice :: (a -> a) -- operator
-> a -- input
-> a -- output
```

Operator should return **same** type as output ...

... but `(10 <) :: Int -> Bool`

Are you following so far ?

`ex1 = doTwice doTwice`

What is the

**type of**`ex1`

?What is the

**type parameter**of`doTwice`

**instantiated**as?

Of course, you can also create polymorphic data types

```
data List a
= Nil -- empty list
| Cons a (List a) -- "cons" of a hd :: a and tl :: List a
```

also known as (defined in standard library)

```
data [a]
= [] -- empty list
| (:) a [a] -- "cons" of a hd :: a and tl :: List a
```

Polymorphic functions and data go hand in hand ...

```
len :: [a] -> Int
len [] = 0
len (_:xs) = 1 + len xs
```

or our friends from last time

```
(++) :: [a] -> [a] -> [a]
head :: [a] -> a
tail :: [a] -> [a]
```

**Note:**

- All the above
**oblivious**to type of values**inside**list - Types are pretty awesome specifications of behavior

```
toUpperString [] = []
toUpperString (c:cs) = (??? c) : toUpperString cs
```

Er, what to put in `???`

Let's ask Hoogle!

```
type XY = (Double, Double)
type Polygon = [XY]
```

```
shiftPoly d [] = []
shiftPoly d (xy:xys) = shiftXY d xy : shiftPoly d xys
```

`shiftXY (dx, dy) (x, y) = (x + dx, y + dy)`

`toUpperString`

and `shiftPoly`

are 93% same!```
shiftPoly d [] = []
shiftPoly d (xy:xys) = shiftXY d xy : shiftPoly d xys
```

```
toUpperString [] = []
toUpperString (c:cs) = (toUpper c) : toUpperString cs
```

`toUpperString`

and `shiftPoly`

are 93% same!```
shiftPoly d [] = []
shiftPoly d (xy:xys) = shiftXY d xy : shiftPoly d xys
toUpperString [] = []
toUpperString (c:cs) = (toUpper c) : toUpperString cs
```

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

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

```
toUpperString = map toUpper
shiftPoly = map shiftXY
```

**Quiz:** Dude, where are the parameters?

```
listAdd [] = 0
listAdd (x:xs) = x + (listAdd xs)
```

```
listMul [] = 1
listMul (x:xs) = x * (listMul xs)
```

```
listAdd [] = 0
listAdd (x:xs) = x + (listAdd xs)
listMul [] = 1
listMul (x:xs) = x * (listMul xs)
```

**Quiz:** What are **differences** between `listAdd`

and `listMul`

?

`foldr`

```
listAdd [] = 0
listAdd (x:xs) = x + (listAdd xs)
listMul [] = 1
listMul (x:xs) = x * (listMul xs)
```

```
foldr op base [] = base
foldr op base (x:xs) = x `op` (foldr op base xs)
```

```
listAdd = foldr (+) 0 -- op = (+), base = 0
listMul = foldr (*) 1 -- op = (*), base = 1
```

`foldr`

```
foldr op base [] = base
foldr op base (x:xs) = x `op` (foldr op base xs)
```

```
len [] = 0
len (x:xs) = 1 + len xs
```

`len`

with `foldr`

!`len = foldr ex2 ex3 `

What should `ex2`

and `ex3`

be?

What is more readable: **HOF** or **Recursion** ?

Patterns appear not just in **toy** functions but in **real code**

To practice, lets develop a small library that *swizzles* text files

Beginner's version, riddled with explicit recursion

Intermediate version, recursion eliminated with higher-order functions

Advanced version,

`swizzle`

and`unswizzle`

without duplication