FP c03 NoAnim
FP c03 NoAnim
Parameter evaluation
Call-by-value
Call-by-name / by-need
Polymorphic types
Lists
Definition
Building lists
Basic functions on lists
Association lists
Parameter evaluation
Question:
When calling a function, when are the actual parameters
evaluated: before or after they replace the formal parameters?
Example (Square)
fun sq ( z ) : int = z * z;
Example (Zero)
Definition
In case of ”call-by-value”, the value of the parameter is sent.
Using call-by-value
Call-by-value is used in ML.
Call-by-value
Example
sq(sq(sq(2))) =
sq(sq(2 * 2)) =
sq(sq(4)) =
sq(4 * 4) =
sq(16) =
16 * 16 =
256
Call-by-value
Example
zero(sq(sq(sq(2)))) =
zero(sq(sq(2 * 2))) =
zero(sq(sq(4))) =
zero(sq(4 * 4)) =
zero(sq(16)) =
zero(16 * 16) =
zero(256) = 0
Call-by-value and the conditional
Example (andalso)
A andalso B is equivalent to if A then B else false
Example
Example
p2(6) =
p2(3) =
false
Call-by-value
Question:
When call-by-value is employed, can we write a function cond
which behaves in the same way as the conditional ?
Example
Example
Example
facter(0) =
cond(true,1,0*facter(-1)) =
cond(true,1,0*cond(false,1,-1*facter(-2))) =
...
Call-by-name
Definition
The expression of the parameter is sent.
Example
zero(sq(sq(sq(2)))) = 0
Call-by-name
Example
sq(sq(sq(2))) =
sq(sq(2)) * sq(sq(2)) =
(sq(2)*sq(2)) * sq(sq(2)) =
((2*2)*sq(2)) * sq(sq(2)) =
(4*sq(2)) * sq(sq(2)) =
(4*(2*2)) * (sq(*sq(2)) =
...
Call-by-need
Definition
Call-by-need (aka ”lazy evaluation”) is similar to call-by-name,
but evaluates an expression only once, when necessary.
Use of call-by-need
Haskell uses call-by-need.
Mechanism
We write [x=E] in order to say that all occurences of x in the
function’s body have access to E.
Call-by-need
Example
sq(sq(sq(2))) =
z*z [z=sq(sq(2))] =
z*z [z=y*y][y=sq(2)] =
z*z [z=y*y][y=2*2] =
z*z [z=4*4] =
16 * 16 =
256
Call-by-need
Example
f n = (2 * n , g n)
g = a hard-to-compute function
h (x,y) = x
h(f 10) = 20
Call-by-need - a not-so-cool example
Example (Sometimes, we can’t escape our fate)
sumacc a [] = a
sumacc a (x:xs) = sumacc (a+x) xs
sumacc 0 [1,2,3] =
((0+1)+2)+3 =
(1+2)+3 = ...
Call-by-need and strict application
Note
In this example, the whole accumulator’s expression is built
before being evaluated. This is an issue for a 10M element list.
sumacc a [] = a
sumacc a (x:xs) = (sumacc $! (a+x)) xs
Call-by-need - strict application
Example (Summing up numbers)
sumacc a [] = a
sumacc a (x:xs) = (sumacc $! (a+x)) xs
sumacc 0 [1,2,3] =
sumacc $! 1 [2,3] =
sumacc 1 [2,3] =
sumacc $! 3 [3] =
Machine:
(processor, memory etc. should be given here)
Call by need - strict application
Machine:
(processor, memory etc. should be given here)
Polymorphism
Definition
A type denotes a set of values and a set of operations on them.
Definition
An object is polymorphic if it could be seen as having more
than one type.
Polymorphism
Definition
Type template (type schema) = a set of type variables which
can get instantiated in order to create specific types.
Definition
Polymorphic function = a function based on a type template.
Example
Example
Definition
Substitution instance = a specifc instantiation of type variables
Definition
An expression is well typed if the type checker is able to find
consistent substitutions for all its type variables.
Example
Type inference
1 is of type int
→ n-1 is of type int
→ n is of type int
→ n*p is integer multiplication
→ p is of type int
→ facti is of type int ∗ int− > int
Overloaded functions
Definition
Overloaded function = a polymorphic function whose type
contains one or more constraints.
Definition
An equality type is a type endowed with an equality predicate. It
is represented by equality type variables, denoted α= , β = , ...
> op =;
val it = fn : ’’a * ’’a -> bool
Polymorphic equality
Example
Equality types
This function could be called only on lists whose elemets are of
equality types, e.g. real, string * int etc.
Projection functions
Definition
Projection function = returns one component of a tuple.
Example
Example
Example
Example
Example
Note
One function could have different types in the same expression.
Innermost firstt:
Outermost firstt:
’a * ’b -> ’a
Some more type inference examples
Example (2 arguments, parentheses)
gcd1 m n = if m == 0 then n
else gcd1 (n ‘mod‘ m) m
Example (1 argument)
Definition
A list is a sequence of values of a specific type.
Example
[1,2,3]
[]
[[1,2], [3,4,5]]
[(1,’’one’’), (2,’’two’’)]
Defining lists
Definition
A list is either empty, or is an ordered pair made of an element
(“head”) and a list (“tail”).
Observation
This definition shows the connection between data and control.
Constructors
Haskell operator : (right associative)
Example
Prelude> 1:2:3:[]
[1,2,3]
Example
Prelude> 1:2:[3]
[1,2,3]
> 1::2::3::[];
val it = [1, 2, 3] : int list
List building
> inter(2,7);
val it = [2, 3, 4, 5, 6, 7] : int list
List processing: recursion + pattern matching
fun prodl [] = 1
| prodl (n::ns) = n * prodl ns;
Observations
1. | means pattern separation; pattern order matters
2. x::xs matched on [1,2,3] binds x to 1 and xs to
[2,3]
3. 1::xs matched on [1,2,3] binds xs to [2,3];
4. 1::xs fails when attempting to match [2,3]
5. x::_::xs matched on [1,2,3,4] binds x to 1 and xs to
[3,4]
List processing without patterns
Example
fun prodl [] = 1
| prodl (n::ns) = n * prodl ns;
Observations
1. using patterns increases code clarity ...
2. ... and allows a better analysis of cases, thus leading to a
better performance of the generated code
List processing: maxl and null
Example
Example
Example
fun hd(x::_) = x;
Warning: Matches are not exhaustive.
Found near fun hd(::( ...)) = x
Example
> hd [1,2,3];
val it = 1 : int
List processing: tail
Example
Example
> tl [1,2,3];
val it = [2, 3] : int list
List processing: length and append
Example
my_length [] = 0
my_length (_:xs) = 1 + my_length xs
Example
infix 4 +++
[] +++ ys = ys
(x:xs) +++ ys = x:(xs +++ ys)
List processing: take and drop
Example
my_take 0 _ = []
my_take k [] = []
my_take k (x:xs) = x:my_take (k-1) xs
Example
my_drop 0 xs = xs
my_drop k [] = []
my_drop k (x:xs) = my_drop (k-1) xs
List processing: reverse
Example
my_rev0 [] = []
my_rev0 (x:xs) = my_rev0 xs ++ [x]
or:
Example
my_rev1 xs = my_rev1acc xs []
where
my_rev1acc [] ys = ys
my_rev1acc (x:xs) ys = my_rev1acc xs (x:ys)
Composed lists: flattening lists
Example
fun flatten [] = []
| flatten (x::xs) = x @ flatten xs;
Example
Example
Definition
Association list = a list of pairs (key, value) with key of type Eq.
Example
val capitals=[("Romania","Bucharest"),
("Poland","Warsaw"),
("Denmark","Copenhagen")];
Example
val dag=[("a","b"),("a","c"),("a","d"),
("b","e"),("c","f"),("d","e"),
("e","f"),("e","g")];
F E T3 = 1, T4 = 2
G D
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
G D
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
T6 ∗ T3 +
G D
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
T6 ∗ T3 +
T5 ∗ T4 +
G D
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D T3 ∗ T6 +
H C
A B
Counting triangulations Tn in a systematic way
F E T3 = 1, T4 = 2
T8 = T7 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D T3 ∗ T6 +
T7
H C
A B
Counting triangulations Tn in a systematic way
F E T2 = 1, T3 = 1, T4 = 2
T8 = T2 ∗ T7 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D T3 ∗ T6 +
T7 ∗ T2
H C
A B
Counting triangulations Tn in a systematic way
F E T2 = 1, T3 = 1, T4 = 2
T8 = T7 ∗ T2 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D T3 ∗ T6 +
T2 ∗ T7
8−1
X
H C T8 = Ti ∗ T8+1−i
i=2
A B
Counting triangulations Tn in a systematic way
F E T2 = 1, T3 = 1, T4 = 2
T8 = T7 ∗ T2 +
T6 ∗ T3 +
T5 ∗ T4 +
T4 ∗ T5 +
G D T3 ∗ T6 +
T2 ∗ T7
8−1
X
H C T8 = Ti ∗ T8+1−i
i=2
n−1
X
Tn = Ti ∗ Tn+1−i
i=2
A B
Computing Tn
Formula
n−1
X
Tn = Ti ∗ Tn+1−i
i=2
trgls n
| n <=3 = 1
| otherwise = sum $ [(trgls i)*(trgls (n+1-i))
| i <- [2..(n-1)] ]
Computing Tn