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?
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 =
let nearby x y =
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
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:
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
What is the type of loopwhile
?
(test) -> (body) -> (return) -> (store) -> output
('a -> bool) -> ('a -> 'a) -> ('a -> 'b) -> 'a -> 'b
More examples:
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
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 =
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 ]
?
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:
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
.
Problem: how do we build the binary search tree?
insert: 'a compare-> 'a -> 'a btree -> 'a btree
cs2041.org