# CSE 230: Winter 2013

### Ranjit Jhala, UC San Diego

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

# Plan

• Polymorphic Functions (#polymorphism)

• Polymorphic Data (#polymorphic-data-structures)

• Bottling Computation Patterns (#bottling-computation-patterns)

# Polymorphic functions

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``````

### For ALL Types `a`

• takes function `f :: a -> a`
• takes value `x` :: a`
• returns an `a`

# Polymorphic functions

Many functions are oblivious to the type of their arguments

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

### Can call with `Int` values

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

Type parameter `a` is instantiated as `Int`

# Polymorphic functions

Many functions are oblivious to the type of their arguments

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

### Or with on `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 Polymorphic

Works on many kinds of values

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

### Crucial for abstraction

• Doing twice is independent of operation and data
• Don't need separate versions for `Int` , `String` ...

# Polymorphism Enables Reuse

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

# Polymorphism: With Great Power ...

... comes great responsibility!

### Recall infix sections

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

Quiz: What is the value of?

``ghci> doTwice (10 <) 100``

# Polymorphism: With Great Power ...

... comes great responsibility!

``ghci> doTwice (10 <) 100``

### Nasty Type Error

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

Operator should return same type as output ...

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

# Quiz

Are you following so far ?

``ex1 = doTwice doTwice``

1. What is the type of `ex1` ?

2. What is the type parameter of `doTwice` instantiated as?

# Polymorphic Data Types

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``````

# Functions Over Polymorphic Data

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]
tail :: [a] -> [a]``````

Note:

1. All the above oblivious to type of values inside list
2. Types are pretty awesome specifications of behavior

# Computation Pattern 1: Iteration

### Convert Strings to UPPERCASE

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

Er, what to put in `???` Let's ask Hoogle!

# Computation Pattern 1: Iteration

### Recall

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

### A function that shifts a Polygon

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

### Helper That Translates One Vertex

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

# A recurring theme: iteration!

### Like humans and monkeys `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``````

# A recurring theme: iteration!

### Like humans and monkeys `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``````

### Capture the Pattern in a Bottle!

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

# Capture the Iteration Pattern in a Bottle! ``````map          :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = (f x) : (map f xs)``````

### Instantiate the pattern

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

Quiz: Dude, where are the parameters?

# Computation Pattern 2: Folding

### Function that Adds elements of a list

``````listAdd []     = 0

# Computation Pattern 2: Folding

### Function that Multiplies elements of a list

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

# Can you spot the pattern?

### Pattern = Shared DNA

``````listAdd []     = 0

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

Quiz: What are differences between `listAdd` and `listMul`?

# Pattern = Shared DNA = `foldr`

``````listAdd []     = 0

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``````

# Pattern = Shared DNA = `foldr`

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

### Recall

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

### Quiz: Rewrite `len` with `foldr`!

``len = foldr ex2 ex3 ``

What should `ex2` and `ex3` be?

# Public Service Announcement

What is more readable: HOF or Recursion ?

# Spotting Patterns In the "Real World"

Patterns appear not just in toy functions but in real code

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

1. Beginner's version, riddled with explicit recursion

2. Intermediate version, recursion eliminated with higher-order functions

3. Advanced version, `swizzle` and `unswizzle` without duplication