Title: A Second Look At ML
1A Second Look At ML
- Additional information
- Programming in ML
- A Gentle Introduction to ML
- Source level debugging in Poly/ML
Download as Power Point file for saving or
printing.
2Outline
- Patterns
- Local variable definitions
- A sorting example
- Functions as parameters
3Variables as Patterns
- Functions of a single parameter
-
-
- n matches and binds to any single int argument.
- f1 3 binds n to 3.
fun f1 n nn val f1 fn int -gt int f1
3 val it 9 int
4Variables as Patterns
- Functions of a tuples parameter
- (a,b) matches and binds a and b any 2-tuple int
argument. - f2 (4, 5) binds a to 4 and b to 5.
fun f2 (a, b) ab val f2 fn int int -gt
int f2(3, 4) val it 12 int f2 (3, 4,
5) Can't unify int int with int int int
5Underscore As A Pattern
fun f _ "yes" val f fn 'a -gt string f
34.5 val it "yes" string f val it
"yes" string f (4,no) val it "yes"
string
- The underscore pattern matches any argument,
single or tuple. - Does not bind to a parameter variable
- Preferred to fun f x "yes"
6Constants As Patterns
fun f 0 "yes" Warning match nonexhaustive
0 gt ... val f fn int -gt string f
0 val it "yes" string
- A pattern can be any equality type
- That excludes reals fun f 0.0 "yes"
- The type of f is int -gt string, but with a match
non-exhaustive warning
7Non-Exhaustive Match
- In the last example, the type of f was int -gt
string, but with a match non-exhaustive warning - Meaning f was defined using a pattern that
didnt cover all the domain type (int), only 0 - Attempting to match a non-existent pattern causes
runtime errors like this
fun f 0 "yes" f 0 val it "yes"
string f 1 Exception- Match raised
8Lists Of Patterns As Patterns
fun f a,_ a Warning match nonexhaustive
a_ nilgt... val f fn 'a list -gt 'a f
1,2 val it 1 int f 1 Exception-
Match raised f 1, 2, 3, 4 Exception- Match
raised
- The example matches lists of length 2
- It treats a and _ as sub-patterns, binding a to
the first list element
9 or Cons Of Patterns As A Pattern
fun f (xxs) x Warning match nonexhaustive
x xs gt ... val f fn 'a list -gt 'a f
1 val it 1 int f 1,2,3 val it 1
int f Exception- Match raised
- xxs matches any non-empty list, and binds x to
the head and xs to the tail - Parenthesis around xxs are for precedence
10 or Cons Of Patterns As A Pattern
fun f (xxs) xs Warning match
nonexhaustive x xsgt... val f fn 'a list
-gt 'a list f 1, 2, 3 val it 2, 3 int
list f 1 val it int list f
Exception- Match raised
11ML Patterns So Far
- Single variable matches and binds to anything
- _ matches anything but binds to nothing
- Constant (of an equality type) matches only that
constant - Tuple of patterns matches any tuple of the right
size, whose contents match the sub-patterns - List of patterns matches any list of the right
size, whose contents match the sub-patterns - Cons () of patterns matches any non-empty list
whose head and tail match the sub-patterns
12Exercise 1
- What are the results?
- fun f n n n
- fun f (a, b) a b
- fun f a,b,_ b
- fun f (xxs) xs
- fun f (xyz) y
- fun f (x,y) x _at_ y
a) f 4 f (4, 5) b) f (3,4) f (3, 4, 5)
c) f 1,2,3 f 1,2 f 1, 2, 3,
4 d) f 1,2,3 f e) f 1,2,3 f
1 f) f (1,2,4,5) f (1_at_2,4)
13Multiple Patterns for Functions
fun f 0 "zero" f 1 "one" Warning
match nonexhaustive 0 gt ...
1 gt ... val f fn int -gt string f 0
val it zero" string f 2 Exception Match
raised
- Define function by listing alternate patterns
- Pattern for function f is f 0 f 1
14Syntax
ltfun-defgt fun ltfun-bodiesgt ltfun-bodiesgt
ltfun-bodygt ltfun-bodygt ''
ltfun-bodiesgtltfun-bodygt ltfun-namegt ltpatterngt
ltexpressiongt
- To list alternate patterns for a function, repeat
the function name in each alternative
fun f 0 "zero" f 1 "one" f 2
"two" f 3 "three"
15Overlapping Patterns
fun f 0 "zero" f _ "non-zero" val f
fn int -gt string f 0 val it "zero"
string f 34 val it "non-zero" string
- Patterns may overlap
- Result returned from the first match for an
argument
16Pattern-Matching Style
- These definitions are equivalent
-
- Pattern-matching style usually preferred
- Often gives shorter and more legible functions
fun f 0 "zero" f _ "non-zero"
fun f n if n 0 then "zero" else
"non-zero"
17Exercise 1.5
f1 2 f1 3 f2 1 f2 2 f3 f3 1 f3 1,
2, 3, 4, 5 f4 f4 1 f4 1, 2, 3, 4, 5
- fun f1 0 "zero f1 2 "two f1 1
"one - fun f2 _ other f2 2 "two
- fun f3 0 f3 a 1 f3 a, b
2 f3 _ 3 - fun f4 0 f4 (abc) 1 f4
(ab) 2 f4 _ 3
18Pattern-Matching Example
Factorial without patterns
fun fact n if n 0 then 1 else n fact(n-1)
Factorial with patterns
fun fact 0 1 fact n n fact(n-1)
19Pattern-Matching Example
Reverse without patterns
fun reverse L if null L then nil else
reverse(tl L) _at_ hd L
Reverse with patterns
fun reverse reverse (firstrest)
reverse rest _at_ first
20More Examples
- Programming pattern frequently occurring in
recursive functionsthat operate on lists - base case (nil) alternative
- recursive case (firstrest) alternative
Sum all elements of a list
fun sum 0 sum (firstrest) first
sum rest
Count number of true values in a list
fun count 0 count (truerest) 1
count rest count (falserest) count rest
21Exercise 1.6
- Count number of true values in a list
- Count number of 5 values in a list using
patterns. - Count number of negative values in a list using
patterns.
fun count 0 count (truerest) 1
count rest count (falserest) count rest
fun count5 L if null L then 0 else if hd L
5 then 1 count5 (tl L) else count5
(tl L)
22More Examples
Return a new list of integers in which original
list incremented by 1 f 1,2,3 returns
2,3,4
fun f L if null L then else (hd L)1
f (tl L)
fun f f (firstrest) first1 f
rest
23More Examples
Return smallest value of a list, note that empty
list is not allowed
fun smallest L if null (tl L) then hd
L else if hd L lt smallest (tl L) then hd L
else smallest (tl L)
fun smallest h h smallest (ht)
if h lt smallest t then h else smallest t
smallest 3,2,5,7 returns 2
24A Restriction
- A variable can occur only once in same pattern
- Not legal, a appears twice
- Use instead
fun f (a,a) for pairs of equal elements f
(x,y) for pairs of unequal elements
fun f (x,y) if (xy) then for pairs of
equal elements else for pairs of unequal
elements
25Patterns Everywhere
val (a,b) (1,2.3) val a 1 int val b
2.3 real val ab 1,2,3,4,5 Warning
binding not exhaustive a b ...
val a 1 int val b 2,3,4,5 int list
- Patterns are not just for function definition
- Here we see that you can use them in a val
- More ways to use patterns, later
26Exercise 2
- What is the result of
- fun f1 (a,b) ab for f1 (3,4)
- fun f2 (abc) c for f2
1,2,3,4 - fun f3 (abc) c for f3
1,2,3 f3 c c for f3 1 - fun f4 (abc) ac f4 c c
for f4 1,2,3 - fun f5 for f5
1,2,3 f5 (abc) ac for
f5 1 f5 c c for f5 - fun f6 for f6 f6 (ht)
h f6 t for f6 1, 2, 3
27Exercise 2 Continued
- Translate into patterns or if-then statements
- fun f x y if y 0 then x else if x 0
then y else x div y - fun f L if null L then else if null (tl
L) then L else hd (tl L)
28Exercise 2 Continued
- Translate into patterns or if-then statements
- fun snoc a a snoc a (ht) h(snoc
a t) - fun rac s if null (tl s) then hd s
else rac (tl s) - fun rdc L if null (tl L) then
else (hd L)rdc(tl L)
29Exercise 2 Continued
- Using patterns, define a function less of
type intint list-gtint list so that
less(e,L) is the list of all integers in L that
are less that e. less(3,1,2,3,4,5,6) returns
1,2 - Use patterns to write a function to construct the
union of two sets. Hint Assume a function
member(3,1,2,3,4,) returns true and
member(3,1,2) returns false.Union(1,2,3,2,3
,4) returns 1,2,3,4
30Exercise 2 Continued
- Using patterns, define a function inc of
type int list-gtint list so that inc L
increments each element of L. inc1,2,3
returns 2,3,4 - Using patterns, define a function dubal of
type int list-gtint list so that dubal L
doubles each element of L. dubal1,2,3 returns
2,4,6
31Exercise 2 Continued
- The Cartesian product pairs each element of two
lists - For example product(1,2,3,4,5,6) is
- 1, 4, 1, 5, 1, 6, 2, 4, 2, 5, 2, 6,
3, 4, 3, 5, 3, 6 - Complete the patterns such that function
- dist (1, 4,5,6) returns 1, 4, 1,
5,1,6. - Note that 1_at_2,3 returns 1, 2, 3
fun product (,_ ) product( _, )
product (ht, L) dist(h,L) _at_
product(t, L)
fun dist (a,) ________ dist (a, ht)
_________________
32Outline
- Patterns
- Local variable definitions
- A sort example
- Functions as parameters
33Local Variable Definitions
- A variable defined with val at the top level is
globally visible from that point forward - val x 3
- let expression restricts definition scope
ltlet-expgt let ltdefinitionsgt in ltexpressiongt
end
34Example with let
let end val it 3 int x Error
unbound variable or constructor x
- The value of a let expression is the value of the
expression in the in part - Variables defined with val between the let and
the in are visible only from the point of
declaration up to the end
val x 1 val y 2 in xy
35Proper Indentation for let
let val x 1 val y 2 in xy end
- For readability, use multiple lines and indent
let expressions like this - Some ML programmers put a semicolon after each
val declaration in a let
36Long Expressions with let
fun days2ms days let val hours days
24.0 val minutes hours 60.0 val
seconds minutes 60.0 in seconds
1000.0 end days2ms 10.0 returns 864000000.0
- The let expression allows you to break up long
expressions and name the pieces - This can make code more readable
37Printing parameters with let
- Useful for debugging
- print Prints string data type
- val _ Defines anonymous variable not used
- Int.toString Converts int n to string
- fun fac 0 1
- fac n
- let
- val _ print (Int.toString n "\n")
- in
- n fac ( n -1 )
- end
38Patterns with let
- let can define computational patterns and
eliminate redundant patterns. - Redundant patterns are computationally expensive
- Recursive Fibonacci is highly redundant
- Running time is exponential, extremely awful.
- Dynamic programming can reduce complexity.
fun fib 0 1 fib 1 1 fib n
fib(n-1)fib(n-2)
39Exponential time 2n execution trace
fun fib 0 1 fib 1 1 fib n
fib(n-1)fib(n-2)
fib 4 gt 5 / \ fib 3 gt
3 fib 2 gt 2 / \ / \ fib 2 gt 2 fib 1
gt 1 fib 1 gt 1 fib 0 gt 1 / \
fib 1 gt 1 fib 0 gt 1
40Patterns with linear time let solution
- Each n gt 0 computes the n and n-1 solution
- val (a,b) f(3) (3, 2), a3, b2.
- (ab,a) returns solution fib(n)ab and
fib(n-1)a
fun fib 0 (1,0) fib 1 (1,1) fib 2
(2,1) ( not needed ) fib 3 (3,2) (
not needed ) fib 4 (5,3) ( not needed
) fib n let val (a, b) fib(n-1)
in (ab,a) end
41Linear n time execution trace
- fun fib 0 (1,0)
- fib 1 (1,1)
- fib 2 (2,1)
- fib 3 (3,2)
- fib 4 (5,3)
- fib n
- let
- val (a, b) fib(n-1)
- in
- (ab,a)
- end
fib 4 gt (5, 3) fib 3 gt (3, 2) fib 2 gt
(2, 1) fib 1 gt (1, 1)
42Patterns with let
- Cases more clearly stated with patterns than
conditionals. - Patterns with let can improve program
readability. - The halve function divides a list into two lists
as a tuple. - halve 1,2,3,4,5 returns (1,3,5,2,4)
- 1 (halve cs)is first element of tuple halve cs
- Recall that 1 (1,3,5,2,4) is 1,3,5.
fun halve (, ) halve a (a,
) halve (abcs) (a(1 (halve
cs)), b(2 (halve cs)))
43halve Execution Trace Runtime 2n
fun halve (, ) halve a (a,
) halve (abcs) (a(1 (halve
cs)), b(2 (halve cs)))
- halve 1,2,3,4,5
-
- a1 b2 cs3, 4, 5 gt (1, 3, 5, 2, 4)
- / \
- a3 b4 cs5 gt (3, 5, 4) a3 b4 cs5
gt (3, 5, 4) -
- a5 gt (5, ) a5 gt (5, )
44Patterns with let Continued
fun halve (, ) halve a (a,
) halve (abcs) let val (x,
y) halve cs in (ax, by)
end
- val (x, y) halve cs
- halve cs returns a tuple such as (3,5,4)
- val (x, y) pattern is a tuple with x as 1 and y
as 2 - halve returns (, )
- halve 4 returns (4, )
- halve 1,2,3,4,5 returns (1,3,5,2,4)
45halve Execution Trace Runtime n
fun halve (, ) halve a (a,
) halve (abcs) let val (x,
y) halve cs in (ax, by)
end
- halve 1,2,3,4,5 a1 b2 cs3, 4, 5
gt (1, 3, 5, 2, 4) a3 b4 cs5
gt (3, 5, 4) a5 gt (5,
)
46Again, Without Good Patterns
let val halved halve cs
val x 1 halved val y 2 halved
in (ax, by) end
- In general, if you find yourself using to
extract an element from a tuple, think twice - Pattern matching usually gives a better solution
47halve At Work
fun halve nil (nil, nil) halve a (a,
nil) halve (abcs) let val
(x, y) halve cs in (ax, by)
end val halve fn 'a list -gt 'a list
'a list halve 1 val it (1,) int list
int list halve 1,2 val it (1,2) int
list int list halve 1,2,3,4,5,6 val
it(1,3,5,2,4,6) int listint list
48Outline
- Patterns
- Local variable definitions
- A sort example
- Functions as parameters
49Merge Sort
- The halve function divides a list into two
nearly-equal parts - This is the first step in a merge sort
- For practice, we will look at the rest
50Example Merge
fun merge (nil, ys) ys merge (xs, nil)
xs merge (xxs, yys) if (x lt y)
then x merge(xs, yys) else y
merge(xxs, ys)
- Merges two sorted lists
- Note default type for lt is int
51Merge At Work
fun merge (nil, ys) ys merge (xs, nil)
xs merge (xxs, yys) if (x lt y) then x
merge(xs, yys) else y merge(xxs,
ys) merge (2,1,3) val it 1,2,3 int
list merge (1,3,4,7,8,2,3,5,6,10) val it
1,2,3,3,4,5,6,7,8,10 int list
52Merge trace
fun merge (nil, ys) ys merge (xs, nil)
xs merge (xxs, yys) if (x lt y) then x
merge(xs, yys) else y merge(xxs, ys)
- merge (1,3,4,2,5,6)
- merge entered val x 1 val xs 3, 4 val y
2 val ys 5, 6 - merge entered val x 3 val xs 4 val y 2
val ys 5, 6 - merge entered val x 3 val xs 4 val y 5
val ys 6 - merge entered val x 4 val xs val y 5
val ys 6 - merge entered val ys 5, 6
- merge returned 5, 6
- merge returned 4, 5, 6
- merge returned 3, 4, 5, 6
- merge returned 2, 3, 4, 5, ...
- merge returned 1, 2, 3, 4, ...
- val it 1, 2, 3, 4, 5, 6 int list
53Example Merge Sort
fun mergeSort nil nil mergeSort a a
mergeSort theList let val (x,
y) halve theList in
merge(mergeSort x, mergeSort y) end
- Merge sort of a list
- Type is int list -gt int list, because of type
already found for merge
54Merge Sort At Work
fun mergeSort nil nil mergeSort a a
mergeSort theList let val (x, y) halve
theList in merge(mergeSort x, mergeSort
y) end val mergeSort fn int list -gt int
list mergeSort 4,3,2,1 val it 1,2,3,4
int list mergeSort 4,2,3,1,5,3,6 val it
1,2,3,3,4,5,6 int list
55Nested Function Definitions
- Define local functions hidden as with local
variables, using a let - Useful for specialized helper functions not
generally useful elsewhere - halve and merge hidden from the rest of the
program this way - Another potential advantage inner function can
refer to variables from outer one (as we will see
in Chapter 12)
56Example Nested mergeSort
( Sort a list of integers. )fun mergeSort nil
nil mergeSort e e mergeSort
theList let ( From the given
list make a pair of lists (x,y),
where half the elements of the
original are in x and half are in y. )
fun halve nil (nil, nil) halve a
(a, nil) halve (abcs)
let val (x, y) halve
cs in (ax, by)
end
continued
57Nested mergeSort Continued
( Merge two sorted lists of integers into a
single sorted list. ) fun merge (nil, ys)
ys merge (xs, nil) xs merge
(xxs, yys) if (x lt y) then x
merge(xs, yys) else y
merge(xxs, ys) val (x, y) halve theList
in merge(mergeSort x, mergeSort y) end
58Complete Nested mergeSort
fun mergeSort nil nil mergeSort e e
mergeSort theList let fun halve nil
(nil, nil) halve a (a, nil)
halve (abcs) let
val (x, y) halve cs
in (ax, by)
end fun merge (nil, ys) ys merge
(xs, nil) xs merge (xxs, yys)
if (x lt y) then x merge(xs,
yys) else y merge(xxs,
ys) val (x, y) halve theList
in merge(mergeSort x, mergeSort y)
end
59Exercise 3
fun fib 0 (1,0) fib 1 (1,1) fib 2
(2,1) ( not needed ) fib 3 (3,2) (
not needed ) fib 4 (5,3) ( not needed
) fib n let val (a, b) fib(n-1)
in (ab,a) end
- For n5, what are a and b after val (a, b)
fib(n-1) - What is returned for fib 5?
60Outline
- Patterns
- Local variable definitions
- A sort example
- Functions as parameters
61Functions as Parameters
- A function executed by another function
fun comp_sq z sq z fun sq x x x comp 4
return 16 comp_sq 4 sq 4 4 4
int comp_sq(int z) return sq(z) int sq(int
x) return xx void main(void) comp_sq(4)
// return 16
62Functions as Parameters
- Functions can be passed as parameters
- Parameter function executed by another function
- Supports abstraction such as repeated function
execution
fun comp f z f z fun sq x x x comp sq 4
return 16 comp sq 4 sq 4 4 4
x
sq
f
z
comp
sq
4
main
int comp(int f(int y), int z) return f(z)
int sq(int x) return xx void main(void)
comp(sq, 4) // return 16
63Apply Functions Repetitively
- int map_sq (int L)
- for (int i0ilt5i) Li sq(Li)
- return L
-
- int sq(int x) return xx
- void main(void)
- int A5 1,2,3,4,5, B
- B map_sq, A)
x
sq
Li
f
f
L
map
sq
A
main
64Iterators Apply Functions Repetitively
- int map(int f(int y), int L)
- for (int i0ilt5i) Li f(Li)
- return L
-
- int sq(int x) return xx
- void main(void)
- int A5 1,2,3,4,5, B
- B map(sq, A)
x
sq
Li
f
f
L
map
sq
A
main
65Functions as Parameters Continued
- Repeated mapping of unary sq function to every
element of one list - Repeated mapping of unary sq function to every
element of one list sq 1sq 2sq 3sq 4
fun sq x x x fun map_sq map_sq
(ht) (sq h)(map_sq t) map_sq 1,2,3,4
returns 1,4,9,16
fun map f map f (ht) (f h)(map
f t) map sq 1,2,3,4 returns 1,4,9,16
66Functions as Parameters Continued
- Repeated mapping of unary inc function to every
element of one list - Repeated mapping of unary inc function to every
element of one list inc 1inc 2inc 3inc
4
fun inc x x 1 fun map_inc
map_inc (ht) (inc h)(map_inc t) map_inc
1,2,3,4 returns 2,3,4,5
fun map f map f (ht) (f h)(map
f t) map inc 1,2,3,4 returns 2,3,4,5
67Functions as Parameters Continued
- Repeated mapping of unary dubal function to every
element of one list - Repeated mapping of unary dubal function to every
element of one list
fun dubal x 2 x fun map_dubal
map_dubal (ht)(dubal h)(map_dubal
t) map_dubal 1,2,3,4 returns 2,4,6,8
fun map f map f (ht) (f h)(map
f t) map dubal 1,2,3,4 returns 2,4,6,8
68Exercise 3.5
- map list 1,2,3,4
- map add 1,2,3,4
- map car 1,1,2,2,3,3
- map 1,2,3,4 abs
- map abs 1,2,3,4
- Some are valid,
- some are not.
- What is the result for
fun map f map f (ht) (f
h)(map f t)
fun list x x fun add x y x y fun car
(ht) h fun abs x if xlt0 then x else x
69Functions as Parameters Continued
- Repeated mapping of binary add function to every
element of two lists with equal number elements - Repeated mapping of binary function to every
element of two lists with equal number elements
fun add x y x y fun map2_add (, )
map2_add (h1t1,h2t2) (add h1
h2)(map2_add (t1, t2))map2_add
(1,2,3,4,5,6) returns 5,7,9
fun map2 (f, , ) map2 (f, h1t1,
h2t2) (f h1 h2)map2 (f, t1, t2) map2
(add,1,2,3,4,5,6) returns 5,7,9
70Exercise 3.6
- map2 (add, 1,2,3,4, 5,6,7,8)
- map2 (tuple, 1,2,3,4, 5,6,7,8)
- map2 tuple 1,2,3,4 5,6,7,8
- map2 (max, 9,2,7,4, 5,6,2,8)
- Some are valid,
- some are not.
- What is the result for
fun map2 (f, , ) map2 (f, h1t1,
h2t2) (f h1 h2)map2 (f, t1, t2)
fun list x x fun add x y x y fun tuple
x y (x,y) fun max x y if xgty then x else
y
71Functions as Parameters Continued
- Filtering list elements by repeated mapping of
odd predicate function to every element of one
list - Filtering list elements by repeated mapping of
predicate function to every element of one list
fun odd x (x mod 2) 1 fun filter_odd
filter_odd (ht) if (odd h)
then h (filter_odd t) else (filter_odd
t) filter_odd 1,2,3,4,5 returns 1,3,5
fun filter f filter f (ht)
if (f h) then h (filter f t) else (filter f
t) filter odd 1,2,3,4,5 returns 1,3,5
72Local functions
- Observe that n parameter remain fixed
- Use let to compute remainder with one parameter
fun prime n let fun remainder 0 true
remainder 1 true remainder m
if (n mod m) 0 then false else
remainder(m-1) in remainder (n-1) end
fun remainder _ 0 true remainder _ 1
true remainder n m if (n mod m)
0 then false else remainder n (m-1) fun prime
n remainder n (n-1)
73Exercise 3.7
- filter odd 1,2,3,4,5
- filter positive 2,1,0,1,2
- filter prime 1,2,3,4,5,6,7,8,9
- Some are valid or not.
- What is the result for
fun filter f filter f (ht)
if (f h) then h (filter f t) else (filter f t)
fun odd x (x mod 2) 1 fun positive x x gt
1 fun prime n let fun remainder 0
true remainder 1 true remainder
m if (n mod m) 0 then false else
remainder(m-1) in remainder (n-1) end
74Functions as Parameters Continued
- Reduction of list by repeated mapping of binary
mult from elements of one list to a base value - Reduction of list by repeated mapping of binary
function from elements of one list to a base
value(mult 1 (mult 2 (mult 3 (mult 4 1))))
fun reduce_mult 1 reduce_mult (ht)
mult h (reduce_mult t) fun mult x y x
y reduce_mult1,2,3,4 returns 4! or 24
fun reduce (f, a, ) a reduce (f, a,
ht) f h (reduce (f, a, t)) reduce
(mult,1,1,2,3,4) returns 4! or 24
75Exercise 4
- map add 1,2,3,4
- reduce (list, , 1,2,3)
- map list 1,2,3,4
- map car 1,1,2,2,3,3
- reduce (add,0,1,2,3,4,5)
- reduce (snoc,,1,2,3)
- Some are valid,
- some are not.
- What is the result for
fun map f map f (ht) (f
h)(map f t) fun reduce (f, a, ) a
reduce (f, a, ht) f h (reduce (f, a,
t)) fun snoc a a snoc a (h
t) h snoc a t
fun list x x fun add x y x y fun car
(ht) h
76Exercise 4 Continued
fun map f map f (ht) (f h)(map
f t)fun reduce (f, a, ) a reduce (f,
a, ht) f h (reduce (f, a, t)) fun map2 (f,
, ) map2 (f, h1t1, h2t2) (f h1
h2)map2 (f, t1, t2)
- Using above functionals and any extra functions
- Multiply each element in the list 1,2,3,4 by 4
using map. - Multiply two lists so that 2,6,12,201,2,3,4
2,3,4,5 using map2. - Find the largest value in a list of positive
numbers using reduce and function that returns
the maximum of two integers.
77Exercise 4 Continued
fun odd x (x mod 2) 1 fun filter f
filter f (ht) if (f h) then h
(filter f t) else (filter f t) filter odd
1,2,3,4,5 returns 1,3,5
- Using above functionals and any extra functions
- Filter a list to retain only prime integers.
Assume a unary predicate prime that returns true
when the parameter is a prime number. - Compute the factorial of each prime integer in a
list. Assume a unary function factorial that
returns the factorial of the parameter.
78Staged computation
- Improves reduce by eliminating fixed parameters
- Observe that f and a parameters remain fixed
- Use let to compute reduce with fixed f and a
fun reduce (f, a, ) a reduce (f, a,
ht) f h (reduce (f, a, t)) fun reduce (f,
a, L) let fun red nil a red (ht)
f(h, red t) in red L end
79Debugging -
Trace function entry and exit values.
PolyML.Compiler.debug trueopen
PolyML.Debug trace true fun fac 0 1 fac n
n fac (n-1) fac 3 fac entered val n 3
fac entered val n 2 fac entered val n 1
fac entered fac returned 1 fac
returned 1 fac returned 2 fac returned 6 val
it 6 int
80Commenting
- Everything between ( and ) in ML is a comment
- Comment every function definition, as in any
language - parameters does it expect
- what does function compute
- how does it do it (if non-obvious)
- etc.