2013-09-06 16 views
5

Ho bisogno di aiuto con il modello corrispondente che confronti 2 numeri. Qualcosa del genere:Come faccio a confrontare xey in F #?

let test x y = 
    match x with 
    | y when x < y -> printfn "less than" 
    | y when x > y -> printfn "greater than" 
    | _ -> printfn "equal" 

In qualche modo cade al caso "_" quando x è 0 e Y è 200. Che cosa sto facendo male qui?

risposta

14

Il problema con il vostro codice è che quando si scrive:

match x with 
| y when x < y -> (...) 

.. vuol dire che si desidera assegnare il valore della x (il <expr> in match <expr> with) per una nuova variabile denominata y (la <pat> in | <pat> when ...) e quindi confrontare questo nuovo (che ora contiene il valore di x) con il valore di x - e quindi restituirà sempre false. È sempre possibile rinominare la variabile legata, in modo che il codice è lo stesso di scrittura:

match x with 
| newY when x < newY -> (...) 

Ora si può vedere perché questo non corrisponde - perché si sta solo confrontando x con se stessa!

pattern matching è particolarmente utile se si dispone di ingressi di qualche struttura più complicata - come tuple o unioni discriminati, liste, array, tipi di opzioni ecc Ma se si vuole semplicemente confrontare i numeri, è molto più facile usare solo if :

let test x y = 
    if x < y then printfn "less than" 
    elif x > y then printfn "greater than" 
    else printfn "equal" 

Nella tua match, non si ha realmente bisogno di legare tutte le variabili - ma la soluzione da John dimostra come si può fare quel lavoro - dice semplicemente, prendere variabili x e y e assegnarli a nuove variabili x e y (che hanno lo stesso nome).

13

Una versione migliore sarebbe quella di corrispondenza modello su entrambi i numeri in questo modo

let test x y = 
    match (x,y) with 
    | (x,y) when x < y -> printfn "less than" 
    | (x,y) when x > y -> printfn "greater than" 
    | _ -> printfn "equal" 
5

Se si consulta con Pattern Matching (F#) su ciò che tipo di pattern matching si utilizza, allora sarebbe il cosiddetto schema di variabili, dove la nuova variabile all'interno dei casi di corrispondenza verrà assegnata al valore dell'espressione di corrispondenza x. Poiché la variabile y all'interno dell'istruzione match ombreggia il parametro di funzione originale , nel primo e nel secondo caso otterrebbe semplicemente il valore di x, quindi le protezioni when falliscono entrambe. Quindi, viene attivata la terza sequenza match match _, in modo da ottenere un ritorno "uguale", come osservato.

si può meglio vedere cosa succede se si esplora il seguente frammento:

let f x y = 
    match x with 
    | y -> y 

e provare con qualcosa come f arg1 arg2; f restituirà sempre arg1 indipendentemente dal valore arg2.

Si può esprimere il tuo intento originale ancora utilizzando l'abbinamento con costante modello spostando confronto argomento in match espressione:

let test x y = 
    match sign (Operators.compare x y) with 
    | 1 -> "greater than" 
    | -1 -> "less then" 
    | _ -> "equal" 
+0

Approccio interessante Gene. –

0

sostituire partita x con-partita y con

let test x y = 
     match y with 
     | y when x < y -> printfn "less than" 
     | y when x > y -> printfn "greater than" 
     | _ -> printfn "equal" 
2

pattern matching è una buona scelta per questo, utilizzare if invece:

if x < y then 
    printfn "less than" 
elif x > y then 
    printfn "greater than" 
else 
    printf "equal" 
2

Simile alla risposta di John Palmer. Credo che la scrittura come questo migliorerà la comprensione di ciò che sta accadendo:

let test x y = 
    match (x,y) with 
    | (a,b) when a < b -> printfn "less than" 
    | (a,b) when a > b -> printfn "greater than" 
    | _ -> printfn "equal" 

In parole povere, quando si utilizza una dichiarazione Match, i termini del modello (vale a dire la parte prima del ->) dichiarano nuovi identificatori. Quando riutilizzi y nel tuo pattern, stai nascondendo l'identificatore precedente e ne crei uno nuovo che ha lo stesso valore della cosa su cui stai facendo corrispondenze, in questo caso l'identificatore x. In altre parole, si confronta sempre il valore di x con se stesso. Come altri hanno notato, questo è probabilmente il migliore con una dichiarazione if.

Problemi correlati