## Functions as values

Example: many searching tasks, such as

``````mem : 'a -> 'a list -> bool
find_all : 'a -> 'a list -> 'a list
assoc : 'a -> ('a * 'b) list -> 'b option``````

Require equality tests. But what makes two elements of type `'a` equal?

``````find : ('a -> bool) -> 'a list -> bool
find_all : ('a -> bool) -> 'a list -> 'a list
assoc_by : ('a -> bool) -> ('a * 'b) list -> 'b option``````

Lambda expressions, partial applications, and composition can be used to construct function parameters.

# Functions as generalization

We can pass functions to generalize the behavior of functions, e.g.

`find_all : ('a -> bool) -> 'a list -> 'a list`

`assoc_by : ('a -> bool) -> ('a*'b) list -> 'b option`

`let find_range lo hi =`

``    find_all (fun x -> x > lo && x < hi)``

`let nearby x y =`

``   assoc_by (fun (x1,y1) -> ((x -. x1)**2. + (y -. y1)**2.) < 1.)``

We can naturally extend this to other examples:

`drop_while`

`drop_until`

`take_while`

What are the types of these functions?

`('a -> bool) -> 'a list -> 'a list`

# Functions as control flow

Java code for hashing a string:

``````int strhash(String str) {
int hash = 5381;
int i = 0;
while (i < str.length()) {
hash = hash*33 + str[i];
i = i+1;
}
return hash
}``````

Notice: the loop has a “store” `(hash,i,str)`, a “body” to update the store, a “test”, and a “return” function of the store:

``````let hstore = (5381,0,str)
let htest (h,i,str) = i < String.length str
let hbody (h,i,str) =
let h' = h*33 + (int_of_char str.[i]) in
let i' = i+1 in (h',i',str)
let hreturn (h,_,_) = h``````

We can express an arbitrary `while` loop as:

``````let loopwhile test body return s =
let rec loop s =
if not (test s) then return s
else loop (body s)
in loop s``````

so the hashing loop becomes

``let strhash str = loopwhile htest hbody hreturn (5381,0,str)``

What is the type of `loopwhile`?

`(test) -> (body) -> (return) -> (store) -> output`

`('a -> bool) -> ('a -> 'a) -> ('a -> 'b) -> 'a -> 'b`

More examples:

``````int sumup(int n) {
int s = 0;
while (n > 0) {
s = s + f(n);
n = n-1;
}
return s;
}``````

`let sumf f =`

``````int least() {
int n = 0;
while (not p(n)) n = n+1;
return n;
}``````

`let least p =`

# Functions as polymorphism

So we can pass functions to generalize the behavior of functions, e.g.

`find_all : ('a -> bool) -> 'a list -> 'a list`

`assoc_by : ('a -> bool) -> ('a*'b) list -> 'b option`

We can naturally extend this to other examples, e.g., `drop_while`, `drop_until`, `take_while`, …

Ordering operations: `listmin`, `listmax`, `sort`

Data structures with arbitrary element types

## Ordering Functions

``````let listmin ls =
let rec loop m = function [] -> m
| h::t -> loop (if h < m then h else m) t
in match ls with [] -> None | h::t -> Some (loop h t)``````

`let lmin cmp ls =`

`let lmax cmp ls =`

## Set operations

Suppose we define a set type as

`type 'a set = 'a list`

We’ll want functions like `mem` and `empty` but also

``````subset : 'a set -> 'a set -> bool
eq_set : 'a set -> 'a set -> bool
union  : 'a set -> 'a set -> 'a set
intersect : 'a set -> 'a set -> 'a set``````

What happens if we take the intersection of `[ fun x -> x ]` and `[ fun x -> x ]`?

## Functions as data values

Functional values can cause polymorphic procedures to fail, e.g.

``````type 'a btree = Empty | Node of 'a * 'a btree * 'a btree

let rec search t e = match t with
| Empty -> false
| Node (v,lt,rt) -> if e = v then true
else if e < v then search lt e
else search rt e``````

`let funtree = Node ((fun x -> x), Empty, Empty)`

`# search funtree (fun x -> x) ;;`

`Exception: Invalid_argument "equal: functional value”.`

So introduce extra parameter:

``````type 'a compare = 'a -> 'a -> int
search : 'a compare -> 'a btree -> 'a -> bool``````

Recall: `T` is a a binary search tree (bst) iff for each `Node(v,lt,rt)` in `T`, every value in `lt` is less than `v` and every value in `rt` is greater than `v`.

``````let rec search cmp t e = match t with
| Empty -> false
| Node (v,lt,rt) -> match cmp e v with
| 0 -> true
| s when s < 0 -> search cmp lt e
| _ -> search cmp rt e``````

Problem: how do we build the binary search tree?

`insert: 'a compare-> 'a -> 'a btree -> 'a btree`

# `cs2041.org`

// reveal.js plugins