Pattern matching in Ocaml
Il pattern matching del linguaggio Ocaml mi permette di confrontare un'espressione con più valori tramite la clausola match with.
match E with
P1 -> E1
| P2 -> E2
| ...
| Pk -> Ek
Dove il simbolo | vuol è l'operatore logico OR, E è l'espressione mentre P sono i pattern da confrontare. Le espressioni E1,...,Ek sono le possibile uscite della funzione.
Nota. Ovviamente tutti i pattern devono essere dello stesso tipo. Allo stesso modo tutte le espressioni in uscita devono essere dello stesso tipo.
Come funziona
Il linguaggio Ocaml verifica tutti i pattern dall'alto verso il basso fino a trovare il pattern con esito positivo.
- Se E = P1, la funzione restituisce E1.
- Se E = P2, la funzione restituisce E2.
- E via dicendo.
Ad esempio, questa funzione riceve in ingresso un numero intero e in uscita una stringa
let confronto = function
1 -> "uno"
| 2 -> "due"
| 3 -> "tre"
Quando richiamo la funzione con il valore 1 la funzione restituisce "uno"
confronto(1);;
- : string = "uno"
Allo stesso modo
confronto 1;;
- : string = "uno"
Quando la richiamo con il valore 2, la funzione restituisce "due"
confronto 2;;
- : string = "due"
Quando la richiamo con il valore 2, la funzione restituisce "due"
confronto 3;;
- : string = "tre"
Se ci fossero due pattern uguali, soltanto il primo verrebbe rilevato.
let confronto = function
1 -> "uno"
| 2 -> "due"
| 2 -> "due bis"
| 3 -> "tre"
In questo caso ci sono due pattern uguali a 2.
Quando passo il parametro 2, il linguaggio Ocaml trova il primo ed esce dal pattern matching senza verificare i successivi pattern.
confronto 2;;
- : string = "due"
Se tutti i pattern danno esito negativo, la funzione restituisce un'eccezione match failure.
#confronto 5
Exception: Match_failure ("//toplevel//", 52,16)
E' comunque possibile fissare un'uscita di default usando una variabile anonima (dummy) nell'ultimo confronto tramite il simbolo "_".
match E with
P1 -> E1
| P2 -> E2
| ...
| _ -> Ek
In quest'ultimo caso, se nessun pattern dà esito positivo, la funzione restituisce l'espressione Ek.
Ad esempio, modifico l'esempio precedente
let confronto = function
1 -> "uno"
| 2 -> "due"
| 3 -> "tre"
| _ -> "not found";;
Ora richiamo la funzione passandogli il valore 5.
Il linguaggio Ocaml verifica tutti i pattern senza trovare un esito positivo.
L'ultimo pattern è però sempre verificato, qualunque sia il parametro passato alla funzione.
Quindi, la funzione restituisce la stringa "not found".
confronto 5;;
- : string = "not found"
E così via.