Quando si scrive un'espressione di corrispondenza del modello, non è possibile utilizzare le funzioni arbitrarie nei propri motivi. È possibile utilizzare solo costruttori, che assomigliano a funzioni non valorizzate. Ad esempio, la funzione "+" è definita su numeri interi. Quindi l'espressione 1+2
viene valutata e dà 3; la funzione "+" viene valutata, quindi non è possibile trovare una corrispondenza su x+y
. Ecco un tentativo di definire una funzione su numeri naturali che controlla se il numero è zero:
let f x = match x with
| 0 -> false
| a+1 -> true
;;
Questo non funziona! Per lo stesso motivo, il tuo esempio con le stringhe non può funzionare. La funzione "^" viene valutata su stringhe, non è un costruttore.
L'abbinamento su x+1
funzionava solo se i numeri erano espressioni simboliche non valutate costituite dall'operatore non valutato +
e una costante simbolica 1
. Questo non è il caso in OCAML. Gli integer sono implementati direttamente attraverso i numeri di macchina.
Quando si abbina un tipo di variante, si corrispondono ai costruttori, che sono espressioni non valutate. Ad esempio:
# let f x = match x with
| Some x -> x+1
| None -> 0
;;
val f : int option -> int = <fun>
Ciò funziona perché il tipo 'a option
è fatto di un'espressione simbolica, come Some x
. Qui, Some
non è una funzione che viene valutata e fornisce qualche altro valore, ma piuttosto un "costruttore", a cui si può pensare come una funzione che non viene mai valutata. L'espressione Some 3
non viene valutata ulteriormente; rimane così com'è. È solo su tali funzioni che è possibile eseguire il pattern-match.
Le liste sono anche espressioni simboliche e non valutate costruite con costruttori; il costruttore è ::
. Il risultato di x :: y :: []
è un'espressione non valutata, che è rappresentata dall'elenco [x;y]
solo per comodità cosmetica. Per questo motivo, è possibile eseguire il pattern-match sugli elenchi.
Inoltre per la spiegazione di seguito: Dove nella stringa deve il compilatore anche dividere la stringa? "abc" a "a" "bc" o "ab" "c" – 0x434D53