pattern matching intesa con operatore cons
-
27-09-2019 - |
Domanda
In "Programmazione F #" Mi sono imbattuto in un pattern-matching come questo (ho semplificato un po '):
let rec len list =
match list with
| [] -> 0
| [_] -> 1
| head :: tail -> 1 + len tail;;
In pratica, ho capito che l'ultima partita riconosce la testa e la coda della lista. Concettualmente, non capisco perché funziona. Per quanto ho capito, è l'operatore :: contro, che aggiunge un valore in posizione della testa di una lista, ma non sembra a me come esso viene utilizzato come operatore qui. Devo capire questo come una "sintassi speciale" per gli elenchi, in cui :: viene interpretato come un operatore o un "pattern matching" a seconda del contesto? O può la stessa idea essere estesa per altri tipi di liste, con altri operatori?
Soluzione
In aggiunta alla risposta di Brian, ci sono alcuni punti che sono degni di nota. La sintassi h::t
può essere usato sia come operatore e come un pattern:
let l = 1::2::[] // As an operator
match l with x::xs -> 1 | [] -> 0 // As a pattern
Questo significa che è un costrutto speciale bit, perché altri operatori (per esempio +
) non possono essere usati come modelli (per decomporre la schiena risultato agli argomenti dell'operatore) - ovviamente, per +
, questo sarebbe ambiguo.
Inoltre, il [_]
modello è interessante, perché è un esempio di modello annidato. Compone:
-
_
- Underscore modello, che corrisponde a qualsiasi valore e non si legano i simboli -
[ <pattern> ]
- Single-elemento della lista modello, che corrisponde a una liste con elementi singoli e corrisponde l'elemento della lista con il<pattern>
nidificato .
Si potrebbe anche match 1::[] with | [x] -> x
scrittura che restituire il valore del singolo elemento (in questo caso 1).
Altri suggerimenti
E 'sintassi speciale per le liste. Si può pensare al tipo list
come un'unione discriminata nel seguente modo:
type list<'T> = // '
| Nil
| Cons of 'T * list<'T>
Se non fosse che non c'è sintassi speciale che rende Nil
essere []
e Cons(h,t)
essere h::t
. Poi è solo normale pattern matching su un'unione discriminata. Fa che aiutano?
(forse vedere anche questo blog .)
E 'usato come un formattatore o formalmente pattern
, `list' è abbinato ai tre modelli:
[]: l'elenco è vuoto
[_] significa che la lista ha un solo elemento, dal momento che non si cura di ciò che l'elemento è, quindi sufficiente mettere _ lì, si può anche utilizzare [a].
mezzi testa :: coda che la lista ha due parti: una testa e una coda.
È possibile visualizzare F # pattern matching come un potente se poi il resto della struttura.