repeat, ma il principale
meccanismo di controllo la ricorsione.
RICORSIONE
La ricorsione una tecnica per risolvere problemi complessi riducendoli a problemi pi
semplici dello stesso tipo.
Per risolvere un problema ricorsivamente occorre:
1. Identificare i casi semplicissimi (casi di base) che possono essere risolti immediatamente
2. Dato un generico problema complesso, identificare i problemi pi semplici dello stesso
tipo la cui soluzione pu aiutare a risolvere il problema complesso
3. Assumendo di saper risolvere i problemi pi semplici (ipotesi di lavoro), determinare
come operare sulla soluzione dei problemi pi semplici per ottenere la soluzione del
problema complesso
f act(n) =
1
se n = 0
n f act(n 1) altrimenti
Variabili locali
Nellespressione
let x = E in F
x una variabile locale tale che :
x ha un valore (quello dellespressione E) soltanto allinterno dellespressione F.
quando tutta lespressione let x = E in F stata valutata, x non ha pi un valore.
# let x = 1+2 in x*8;;
- : int = 24
# x;;
Characters 0-1:
x;;
^
Unbound value x
Il legame locale sovrascrive altri eventuali legami globali
# let x="pippo";;
val x : string = "pippo"
# let x="pluto" in "ciao "^x;;
- : string = "ciao pluto"
# x;;
- : string = "pippo"
(* concatenazione di stringhe *)
# fraction(32,28)
d
28
n
32
fraction function(n,d) => ...
...
...
com
4
d
28
n
32
fraction function(n,d) => ...
...
...
in (n/com, d/com)
il valore (8,7)
d
28
n
32
fraction function(n,d) => ...
...
...
- :
# let x=3*8
in let y=x+1 (* il valore di x e visibile *)
in (x+y) mod 5;; (* x+y=24+25 *)
Esercizio
Qual il valore dellespressione seguente?
let x = 3*8 in let x=x+1 in (x+x) mod 5
E qual il valore di x dopo la valutazione dellespressione?
mult
: int * int -> int
times
: int -> int -> int
times 5 :
int -> int
calcola
10
X
(2 k)
k=1
Catturare uneccezione
Uneccezione pu essere catturata per implementare procedure di questo tipo:
calcolare il valore di E
se nel calcolo di tale valore si verifica un errore
allora .....
# try 4 * fact(-1)
with NegativeNumber -> 0;;
- : int = 0
Attenzione:
Se E di tipo exn:
1. E pu essere il valore di qualunque funzione
2. E pu essere argomento di qualunque funzione
Le eccezioni sono eccezioni alla tipizzazione forte.
Cos un pattern?
Un pattern una espressione costituita mediante variabili e costruttori di tipo.
Per i tipi introdotti fin qui, i costruttori sono tutti e solo:
i valori del tipo int, float, bool, char, string, unit
i costruttori di tuple (coppie, triple, ...), cio parentesi e virgole ( , ), ( , , ) ...
Esempi:
x un pattern, in quanto variabile;
"pippo" un pattern, in quanto valore, quindi costruttore del tipo string;
2.0 un pattern, in quanto valore, quindi costruttore del tipo float;
(x,y) un pattern, in quanto espressione ottenuta a partire da variabili e costruttori
del tipo coppia;
(0,x) un pattern, in quanto espressione ottenuta a partire da variabili, costruttori
del tipo int e costruttori del tipo coppia;
(x,true,y) un pattern, in quanto espressione ottenuta a partire da variabili,
costruttori del tipo bool e costruttori del tipo tripla;
x+y NON un pattern in quanto + non un costruttore;
-n
Esempi
Pattern
"pippo"
"pippo"
"pippo"
x
x
x
("pippo", true)
("pippo", true)
("pippo", x)
(n,m)
(n,m,k)
(n,m,k)
(n,(m,k))
(n,(m,k))
Espressione
"pippo"
"pluto"
0
"pippo"
"pi""ppo"
3*8
("pippo", true)
("pippo", 3<0)
("pippo", 3<0)
(2.0, 3<0)
Pattern Matching
Successo
Fallimento
ERRORE
x="pippo"
x="pippo"
x=24
Successo
Fallimento
x=false
n=2.0
m=false
(2.0, 3<0)
Fallimento
(2.0, 3*8, 3>0)
n=2.0
m=24
k=true
(2.0, 3*8, 3>0)
Fallimento
(2.0, (3*8, 3>0))
n=2.0
m=24
k=true
Nota : Il pattern matching di un pattern costituito da una sola variabile con qualunque
espressione, di qualunque tipo, ha sempre esito positivo.
sort (x,y)
- :
Pattern
_
("pippo", _)
(n,_,m)
(_,_)
(_,_)
Espressione
"pippo"
("pippo", 3<0)
(2.0, 3*8, 3>0)
Pattern Matching
Successo
Successo
n=2.0
m=true
(2.0, 3*8, 3>0)
Fallimento
(2.0, (3*8, 3>0))
Successo
Espressioni match
match E with
P1 -> E1
| P2 -> E2
| ...
| Pk -> Ek
I pattern P1, ..., Pn devono essere tutti dello stesso tipo, e dello stesso tipo di E.
Le espressioni E1, ..., En devono essere tutte dello stesso tipo T .
Tipo dellespressione match ...: T .
P attern1 -> E1
| P attern2 -> E2
...
| P atternn -> En
# fact 2
n * 1
fact n =
n*fact(n-1)
n
2
fact function n -> ...
...
...
n
1
n
2
fact function n -> ...
...
...
riporta 1
fact n =
n*fact(n-1)
n
1
n
2
fact function n -> ...
...
...
n * 1
n
2
fact function n -> ...
...
...
riporta 2
fact n = 1
n
0
n
1
n
2
fact function n -> ...
...
...
riporta 1
- :
int = 2
VALUTAZIONE DI ESPRESSIONI
MODELLO DI CALCOLO:
CALCOLARE = RIDURRE
# let square x = x * x;;
val square : int -> int = <fun>
square (3*2) ==> square 6 ==> 6 * 6 ==> 36
square (3*2) ==> (3*2)*(3*2) ==> 6*(3*2) ==> 6*6 ==> 36
Regole di calcolo:
CALL BY VALUE: calcolare il valore dellargomento prima di applicare una funzione
CALL BY NAME: applicare la funzione prima di aver calcolato il valore dellargomento
Regola di calcolo di ML: call by value
Eccezioni: espressioni condizionali, operatori booleani
Efficienza?
# let zero x = 0;;
val zero : a -> int = <fun>
zero(square 6) ==> zero(6*6) ==> zero 36 ==> 0
zero(square 6) ==> 0
Non tutte le funzioni utilizzano sempre tutti i loro argomenti.