# Higher-Order Programming Patterns

```
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
module Lec3 where
```

```
import Prelude hiding (map, foldr, filter, pred, sum, product)
import Data.Char
import Test.HUnit
```

# Functions Are Data

In all functional languages, functions are *first-class* values, meaning that they can be treated just as you would any other data.

You can pass functions around in *any* manner that you can pass any other data around in. For example, suppose you have a simple functions `plus1`

and `minus1`

defined via the equations

```
plus1 :: Int -> Int
plus1 x = x + 1
```

```
minus1 :: Int -> Int
minus1 x = x - 1
```

Now, you can make a pair containing functions.

```
funp :: (Int -> Int, Int -> Int)
funp = undefined
```

Or you can make a list containing functions (as long as they have the same type):

```
funs :: [Int -> Int]
funs = undefined
```

## Taking Functions as Input

This innocent looking feature makes a langage surprisingly brawny and flexible, because now, we can write *higher-order* functions that take functions as input and return functions as output! Consider:

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

```
dtTests = runTestTT (TestList [ doTwice plus1 4 ~?= 6,
doTwice minus1 5 ~?= 3 ])
```

Here, `doTwice`

takes two inputs: a function `f`

and value `x`

, and returns the the result of applying `f`

to `x`

, and feeding that result back into `f`

to get the final output. Note how the raw code is clearer to understand than my long-winded English description!

Last time we talked about how programs execute in Haskell - we just substitute equals for equals. Let's think about an example with doTwice:

```
doTwice plus1 10 == plus1 (plus1 10) {- unfold doTwice -}
== plus1 (10 + 1) {- unfold plus1 -}
== (10 + 1) + 1 {- unfold plus1 -}
== 12 {- old-school arithmetic -}
```

## Returning Functions as Output

Similarly, it can be useful to write functions that return new functions as output. For example, rather than writing different versions `plus1`

, `plus2`

, `plus3`

*etc.* we can just write a single function `plusn`

as

```
plusn :: Int -> (Int -> Int)
plusn n = f
where f x = x + n
```

That is, `plusn`

returns as output a function `f`

which itself takes as input an integer `x`

and adds `n`

to it. Let's use it

```
plus10 :: Int -> Int
plus10 = undefined
```

```
minus20 :: Int -> Int
minus20 = undefined
```

`pmTests = runTestTT (TestList [plus10 10 ~?= 20, minus20 30 ~?= 10])`

Note the types of the above are `Int -> Int`

. That is, `plus10`

and `minus20`

are functions that take in an integer and return an integer (even though we didn't explicitly give them an argument).

## Partial Application

In regular arithmetic, the `-`

operator is *left-associative*. Hence,

` 2 - 1 - 1 == (2 - 1) - 1 == 0`

(and not `2 - (1 - 1) == 2`

!). Just like `-`

is an arithmetic operator that takes two numbers and returns an number, in Haskell, `->`

is a *type operator* that takes two types, the input and output, and returns a new function type. However, `->`

is *right-associative*: the type

`Int -> Int -> Int`

is equivalent to

`Int -> (Int -> Int)`

That is, the first type of function, which takes two Ints, is in reality a function that takes a single Int as input, and returns as *output* a function from Ints to Ints! Equipped with this knowledge, consider the function

```
plus :: Int -> Int -> Int
plus m n = m + n
```

Thus, whenever we use `plus`

we can either pass in both the inputs at once, as in

plus 10 20

or instead, we can *partially* apply the function, by just passing in only one input

```
plusfive :: Int -> Int
plusfive = undefined
```

thereby getting as output a function that is *waiting* for the second input (at which point it will produce the final result).

`pfivetest = runTestTT (plusfive 1000 ~?= 1005)`

So how does this execute? Again *substitute equals for equals*

```
plusfive 1000 == plus 5 1000 {- definition of plusfive -}
== 5 + 1000 {- unfold plus -}
== 1005 {- arithmetic -}
```

Finally, by now it should be pretty clear that `plusn n`

is equivalent to the partially applied `plus n`

.

If you have been following so far, you should know how this behaves.

`doTwicePlus20 = doTwice (plus 20)`

First, see if you can figure out the type.

Next, see if you can figure out how this evaluates.

` doTwicePlus20 0 == ??`

`doTPtest = runTestTT (doTwicePlus20 0 ~?= undefined)`

## Anonymous Functions

As we have seen, with Haskell, it is quite easy to create function values that are not bound to any name. For example the expression `plus 1000`

yields a function value that is not bound to any name.

We will see many situations where a particular function is only used once, and hence, there is no need to explicitly name it. Haskell provides a mechanism to create such *anonymous* functions. For example,

`\x -> x + 1`

is an expression that corresponds to a function that takes an argument `x`

and returns as output the value `x + 2`

. The function has no name, but we can use it in the same place where we would write a function.

```
anonTests = runTestTT (TestList [ (\x -> x + 1) 100 ~?= 101,
doTwice (\x -> x + 1) 100 ~?= 102 ])
```

Of course, we could name the function if we wanted to

```
plus1' :: Int -> Int
plus1' = \x -> x + 1
```

Indeed, in general, a function defining equation

f x1 x2 ... xn = e

is equivalent to

f = 1 x2 ... xn -> e

## Infix Operations and Sections

In order to improve readability, Haskell allows you to use certain functions as *infix* operations: a function whose name appears in parentheses can be used as an infix operation. My personal favorite infix operator is the application function, defined like this:

```
($) :: (a -> b) -> a -> b
f $ x = f x
```

Huh? Doesn't seem so compelling does it? It's just application.

Actually, its very handy because it has different precedence than normal application. For example, I can write:

minus20 $ plus 30 32

Which means the same as:

minus20 (plus 30 32)

That is, Haskell interprets everything after the `$`

as one argument to `minus20`

. I couldn't do this by writing:

minus20 plus 30 32

Because Haskell would think this was the application of `minus20`

to the three separate arguments `plus`

, `30`

and `32`

.

We will see many other such operators in the course of the class; indeed many standard operators including that we have used already are defined in this manner in the standard library. For example:

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

Furthermore, Haskell allows you to use *any* function as an infix operator, simply by wrapping it inside backticks.

```
anotherFive :: Int
anotherFive = 2 `plus` 3
```

Recall the clone function from last time.

```
clone x n | n == 0 = []
| otherwise = x : clone x (n-1)
```

We can invoke it in an infix-style like so:

```
threeThirties :: [Int]
threeThirties = 30 `clone` 3
```

To further improve readability, Haskell allows you to use *partially applied* infix operators, ie infix operators with only a single argument. These are called *sections*. Thus, the section `(+1)`

is simply a function that takes as input a number, the argument missing on the left of the `+`

and returns that number plus `1`

.

```
anotherFour :: Int
anotherFour = doTwice (+2) 0
```

Similarly, the section `(1:)`

takes a list of numbers and returns a new list with `1`

followed by the input list. So we should expect this behavior

`dtcTest = runTestTT $ doTwice (1:) [2..5] ~?= [1,1,2,3,4,5]`

# Polymorphism

We used to `doTwice`

to repeat an arithmetic operation, but the actual body of the function is oblivious to how `f`

behaves.

We say that `doTwice`

is *polymorphic* in that it works with different types of values, eg functions that increment integers and concatenate strings. This is vital for *abstraction*. The general notion of repeating, ie *doing twice* is entirely independent from the types of the operation that is being repeated, and so we shouldn't have to write separate repeaters for integers and strings. Polymorphism allows us to *reuse* the same abstraction `doTwice`

in different settings.

Of course, with great power, comes great responsibility.

The section `(10 <)`

takes an integer and returns `True`

iff the integer is greater than `10`

```
greaterThan10 :: Int -> Bool
greaterThan10 = (10 <)
```

However, because the input and output types are different, it doesn't make sense to try `doTwice greaterThan10`

. A quick glance at the type of doTwice would tell us this:

doTwice :: (a -> a) -> a -> a

The `a`

above is a *type variable*. The signature above states that the first argument to `doTwice`

must be a function that maps values of type `a`

to `a`

, i.e., must produce an output that has the same type as its input (so that that output can be fed into the function again!). The second argument must also be an `a`

at which point we may are guaranteed that the result from `doTwice`

will also be an `a`

. The above holds for *any* `a`

which allows us to safely re-use `doTwice`

in different settings.

Of course, if the input and output type of the input function are different, as in `greaterThan10`

, then the function is incompatible with `doTwice`

.

Ok, to make sure you're following, can you figure out what this does?

`ex1 = doTwice doTwice`

## Polymorphic Data Structures

Polymorphic functions which can *operate* on different kinds of values are often associated with polymorphic data structures which can *contain* different kinds of values. These are also represented by types containing type variables.

For example, the list length function

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

doesn't peek inside the specific entries in the list; it only counts how many there are. This property is crisply specified in the function's signature, which states that we can invoke `len`

on any kind of list. The type variable `a`

is a placeholder that is replaced with the actual type of the list at different application sites. Thus, in the below instances, `a`

is replaced with `Double`

, `Char`

and `[Int]`

respectively.

```
len [1.1, 2.2, 3.3, 4.4] :: Int
len "mmm donuts!" :: Int
len [[], [1], [1,2], [1,2,3]] :: Int
```

Most standard list manipulating functions, for example those in the standard library Data.List have generic types. You'll find that the type signature contains a surprising amount of information about how the function behaves.

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

# Bottling Computation Patterns With Polymorphic Higher-Order Functions

The tag-team of polymorphism and higher-order functions is the secret sauce that makes FP so tasty. It allows us to take arbitrary, *patterns of computation* that reappear in different guises in different places, and crisply specify them as safely reusable strategies. That sounds very woolly (I hope), let's look at some concrete examples.

## Computation Pattern: Iteration

Let's write a function that converts a string to uppercase. Recall that in Haskell, a `String`

is just a list of `Char`

s. We must start with a function that will convert an individual `Char`

to its uppercase version. Once we find this function, we will simply *walk over the list*, and apply the function to each `Char`

.

How might we find such a transformer? Lets query Hoogle for a function of the appropriate type! Ah, we see that the module `Data.Char`

contains a function.

` toUpper :: Char -> Char`

Now, we can write the simple recursive function:

```
toUpperString :: String -> String
toUpperString = undefined
```

As you might imagine, this sort of recursion appears all over the place. For example, suppose I represent a location on the plane using a pair of `Double`

s (for the x- and y- coordinates) and I have a list of points that represent a polygon.

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

Now, its easy to write a function that *shifts* a point by a specific amount.

```
shiftXY :: XY -> XY -> XY
shiftXY (dx, dy) (x, y) = undefined
```

How would we translate a polygon? Just walk over all the points in the polygon and translate them individually.

```
shiftPoly :: XY -> Polygon -> Polygon
shiftPoly _ [] = []
shiftPoly d (xy:xys) = undefined
```

Now, in a lesser language, you might be quite happy with the above code. But what separates a good programmer from a great one is the ability to *abstract*.

The functions `toUpperString`

and `shiftPoly`

share the same computational structure - they walk over a list and apply a function to each element. We can abstract this common pattern out as a higher-order function, `map`

. The two differ only in what function they apply to each list element, so we'll just take that as an input!

`map = undefined`

The type of `map`

tells us exactly what it does. That is, it takes an `a -> b`

transformer and list of `a`

values, and transforms each value to return a list of `b`

values. We can now safely reuse the pattern, by *instantiating* the transformer with different specific operations.

```
toUpperString' :: String -> String
toUpperString' = undefined
```

```
shiftPoly' :: XY -> Polygon -> Polygon
shiftPoly' d = undefined
```

Let's make sure our refactoring didn't break anything!

```
testMap = runTestTT $ TestList $
[ toUpperString' "abc" ~?= toUpperString "abc",
shiftPoly' (0.5,0.5) [(1,1),(2,2),(3,3)] ~?=
shiftPoly (0.5,0.5) [(1,1),(2,2),(3,3)] ]
```

Much better.

By the way, what happened to the list parameters of `toUpperString`

and `shiftPoly`

? Two words: *partial application*. In general, in Haskell, a function definition equation

`f x = e x`

is identical to

`f = e`

as long as `x`

doesn't appear in `e`

. Thus, to save ourselves the trouble of typing, and the blight of seeing the vestigial `x`

, we often prefer to just leave it out altogether.

As an exercise, to prove to yourself using just equational reasoning (using the different equality laws we have seen) that the above versions of `toUpperString`

and `shiftPoly`

are equivalent.

We've already seen a few other examples of the map pattern. Recall the `listIncr`

function, which added 1 to each element of a list:

```
listIncr :: [Int] -> [Int]
listIncr [] = []
listIncr (x:xs) = (x+1) : listIncr xs
```

We can write this more cleanly with map, of course:

```
listIncr' :: [Int] -> [Int]
listIncr' = undefined
```

## Computation Pattern: Folding

Once you've put on the FP goggles, you start seeing computation patterns everywhere.

Lets write a function that *adds* all the elements of a list.

```
sum :: [Int] -> Int
sum = undefined
```

Next, a function that *multiplies* the elements of a list.

```
product :: [Int] -> Int
product = undefined
```

Can you see the pattern? Again, the only bits that are different are the `base`

case value, and the function being used to combine the list element with the recursive result at each step. We'll just turn those into parameters, and lo!

`foldr = undefined`

Now, each of the individual functions are just specific instances of the general `foldr`

pattern.

```
sum', product' :: [Int] -> Int
sum' = undefined
product' = undefined
```

```
foldrTest = runTestTT $ TestList [
sum' [1,2,3] ~?= sum [1,2,3],
product' [1,2,3] ~?= product [1,2,3]
]
```

To develop some intuition about `foldr`

lets "run" it a few times by hand.

```
foldr f base [x1,x2,...,xn]
== f x1 (foldr f base [x2,...,xn]) {- unfold -}
== f x1 (f x2 (foldr f base [...,xn])) {- unfold -}
== f x1 (f x2 (... (f xn base))) {- unfold -}
```

Aha! It has a rather pleasing structure that mirrors that of lists; the `:`

is replaced by the `f`

and the `[]`

is replaced by `base`

. Thus, can you see how to use it to eliminate recursion from the recursion from our list length function:

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

```
len' :: [a] -> Int
len' = undefined
```

How would you use foldr to eliminate the recursion from:

```
factorial :: Int -> Int
factorial 0 = 1
factorial n = n * factorial (n-1)
```

Like this:

```
factorial' :: Int -> Int
factorial' n = undefined
```

OK, one more. The standard list library function `filter`

has this type:

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

The idea is that it the output list should contain only the elements of the first list for which the input function returns `True`

.

So:

```
filterTests :: Test
filterTests = TestList
[ filter (>10) [1..20] ~?= [11..20],
filter (\l -> sum l <= 42) [ [10,20], [50,50], [1..5] ]
~?= [[10,20],[1..5]] ]
```

Can we implement filter using foldr? Sure!

`filter pred = undefined`

## Which is more readable? HOFs or Recursion

As a beginner, you might think that the explicitly recursive versions of some of these functions are easier to follow than the `map`

and `foldr`

versions. However, as you write more Haskell, you will find the latter are far easier to follow, because `map`

and `foldr`

encapsulate such common patterns that you'll become completely accustomed to thinking in terms of them and other similar abstractions.

In contrast, explicitly writing out the recursive pattern matching is lower-level. Every time you see a recursive function, you have to understand how the knots are tied, and worse, there is potential for making silly off-by-one type errors if you re-jigger the basic strategy every time.

As an added bonus, it can be quite useful and profitable to *parallelize* and *distribute* the computation patterns (like `map`

and `foldr`

) in just one place, thereby allowing arbitrary hundreds or thousands of instances to benefit in a single shot!.

We'll see some other similar patterns later on.

# Spotting Patterns In The "Real" World

It was all well and good to see the patterns in tiny "toy" functions. Needless to say, these patterns appear regularly in "real" code, if only you know to look for them. We didn't get to this in class, but for additional practice you can look at the extended example on your own.

Acknowledgements: This lecture is based on notes by Ranjit Jhala, Winter 2011

```
main :: IO ()
main = putStrLn "This is Lec3"
```

## News :

Welcome to CIS 552!

See the home page for basic
information about the course, the schedule for the lecture notes
and assignments, the resources for links to the required software
and online references, and the syllabus for detailed information about
the course policies.