2013-05-17 44 views
5

Mọi người có thể giải thích cho tôi về đoạn mã này không?Chức năng khớp mẫu trong OCaml

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

Khi tôi thực thi safeDiv 3 0, các mn trong trường hợp này là gì?

Trong trường hợp chung, khi nào chức năng phù hợp với mẫu đầu tiên và thứ hai?

Trả lời

8

Khi bạn thực hiện safe_division 3 0, trước tiên, 3 bị ràng buộc với tên n và phía bên phải của tuyên bố sau đó được đánh giá.

Đây là số function, vì vậy đối số tiếp theo, 0, được đối sánh với các trường hợp khác nhau theo thứ tự. Ở đây, nó khớp với trường hợp đầu tiên, vì vậy phía bên tay phải được đánh giá và một ngoại lệ được ném ra. Trong trường hợp này, tên m không bao giờ bị ràng buộc với bất cứ điều gì.

Nếu đối số thứ hai được, ví dụ, 1, sau đó nó sẽ xuất hiện trường hợp thứ hai (trường hợp này phù hợp với tất cả các giá trị có thể dù sao, đó là một trường hợp mặc định), ràng buộc tên m với giá trị 1 và sau đó trả lại kết quả của n/m.

7
let safe_division n 

định nghĩa một hàm mà kiểu là int -> ...

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

định nghĩa một hàm mà kiểu là int -> int

Vì vậy, các loại kết quả của toàn bộ là int -> int -> int trong đó n là đối số đầu tiên và m là đối số thứ hai. Int cuối cùng là kết quả.

11

Nó rất dễ dàng để xem những gì này có nghĩa là khi bạn nhận ra rằng

let f x y z = e 

chỉ là một đoạn ngắn tay cho

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

Đó là một chức năng của các đối số n thực sự là chức năng n lồng nhau của 1 đối số. Đại diện đó được gọi là "currying". Đó là những gì cho phép bạn áp dụng một phần chức năng, ví dụ:

let g = f 3 

trả về một hàm của 2 đối số.

Tất nhiên, chữ viết tắt ở trên có thể được trộn tự do với biểu mẫu rõ ràng ở bên phải và đó là ví dụ của bạn. Bạn có thể desugar nó vào:

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 

chỉ là tương đương với:

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

Note funfunction là hơi khác nhau. Xem: http://caml.inria.fr/pub/docs/manual-ocaml/expr.html#sec121

Các vấn đề liên quan