2013-05-17 14 views
5

Tutti possono spiegarmi questo codice?Funzioni di corrispondenza dei modelli in OCaml

let safe_division n = function 
| 0 -> failwith "divide by 0" 
| m -> n/m 

Quando ho excute safeDiv 3 0, qual è il m e n in questo caso?

In genere, quando la funzione corrisponde al primo e al secondo schema?

risposta

8

Quando si esegue safe_division 3 0, il primo, 3 è associato al nome n e il lato destro della dichiarazione viene quindi valutato.

Questo è un function, quindi l'argomento successivo, 0, viene confrontato con i diversi casi, nell'ordine. Qui, corrisponde al primo caso, quindi viene valutato il lato destro e viene generata un'eccezione. In questo caso, il nome m non è mai associato a qualcosa.

Se il secondo argomento è stato, per esempio, 1, allora sarebbe abbinato secondo caso (questo caso corrisponde a ogni valore possibile in ogni caso, si tratta di un caso di default), vincolante il nome m al valore 1 e poi tornare la risultato di n/m.

7
let safe_division n 

definire una funzione di quale tipo è int -> ...

function 
| 0 -> failwith "divide by 0" 
| m -> n/m 

definire una funzione che tipo è int -> int

Così il tipo risultante del tutto è int -> int -> int dove n è il primo argomento e m il secondo. L'ultimo int è il risultato.

11

E 'facile vedere che cosa questo significa che una volta ti rendi conto che

let f x y z = e 

è solo una breve mano per

let f = function x -> function y -> function z -> e 

Cioè, una funzione di n argomenti in realtà funzioni n nidificate di 1 argomento. Quella rappresentazione è chiamata "currying". È ciò che ti consente di applicare una funzione parzialmente, ad es.

let g = f 3 

restituisce una funzione di 2 argomenti.

Ovviamente, la mano breve sopra può essere mescolata liberamente con la forma esplicita a destra, ed è quello che fa il tuo esempio. È possibile desugar in:

let safe_division = function n -> function 
            | 0 -> failwith "divide by 0" 
            | m -> n/m 
0
let safe_division n = function 
| 0 -> failwith "divide by 0" 
| m -> n/m 

è proprio equivalente a:

let safe_division n = fun x -> match x with 
| 0 -> failwith "divide by 0" 
| m -> n/m 

Nota fun e function sono leggermente diverse. Vedi: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html#sec121