2013-09-06 60 views
5

Tôi cần trợ giúp với mẫu phù hợp có thể so sánh 2 số. Một cái gì đó như thế:Làm cách nào để so sánh x và y trong F #?

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

Bằng cách nào đó nó rơi vào trường hợp "_" khi x là 0 và y là 200. Tôi đang làm gì sai ở đây?

Trả lời

14

Vấn đề với mã của bạn là khi bạn viết:

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

.. nó có nghĩa là bạn muốn gán giá trị của x (các <expr> trong match <expr> with) cho một biến mới có tên y (các <pat> trong | <pat> when ...) và sau đó so sánh mới này y (hiện có chứa giá trị x) với giá trị x - và do đó, điều này sẽ luôn trả lại false. Bạn luôn có thể đổi tên các biến ràng buộc, do đó, mã của bạn cũng giống như viết:

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

Bây giờ bạn có thể thấy tại sao điều này không bao giờ phù hợp - bởi vì bạn chỉ là so sánh x với bản thân!

Kết hợp mẫu đặc biệt hữu ích nếu bạn có đầu vào của một số cấu trúc phức tạp hơn - như tuples hoặc phân biệt đối xử, danh sách, mảng, loại tùy chọn v.v. Nhưng nếu bạn chỉ muốn so sánh các số, sẽ dễ dàng hơn nhiều khi chỉ sử dụng if :

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

Trong match của bạn, bạn không thực sự cần phải ràng buộc bất kỳ biến - nhưng giải pháp của John cho thấy làm thế nào bạn có thể làm cho rằng công việc - nó chỉ đơn giản nói, hãy biến xy và gán chúng cho các biến mới xy (chỉ có cùng tên).

13

Một phiên bản tốt hơn sẽ được phù hợp với mô hình trên cả hai con số như vậy

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

Nếu bạn tham khảo ý kiến ​​với Pattern Matching (F#) khi loại mô hình phù hợp với bạn sử dụng, sau đó nó sẽ được cái gọi là biến trong pattern, trong đó các biến mới y trong các trường hợp khớp sẽ được gán giá trị của biểu thức đối sánh x. Vì biến số y này bên trong thông số match đổ bóng thông số hàm ban đầu y, trong trường hợp đầu tiên và thứ hai y sẽ đơn giản nhận giá trị x, do đó when bảo vệ cả hai đều không thành công. Sau đó, trường hợp bắt gặp tất cả các trường hợp thứ ba _ đá vào, vì vậy bạn nhận được "bằng nhau" trở lại, như đã quan sát.

Bạn tốt hơn có thể xem những gì sẽ xảy ra nếu bạn khám phá những đoạn sau đây:

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

và thử nó với một cái gì đó giống như f arg1 arg2; f sẽ luôn trả lại arg1 bất kể giá trị arg2.

Bạn có thể bày tỏ ý định ban đầu của bạn vẫn còn sử dụng phù hợp với mẫu liên tục bằng cách di chuyển so sánh đối số vào match biểu:

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

Cách tiếp cận thú vị Gene. –

0

thay trận đấu x với-trận đấu y với

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

mẫu phù hợp là một lựa chọn tốt cho rằng, sử dụng if thay vì:

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

Tương tự như câu trả lời John Palmer. Tôi nghĩ rằng cách viết nó như thế này sẽ cải thiện sự hiểu biết của bạn về những gì đang xảy ra:

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" 

Về đồng bằng, khi bạn sử dụng một tuyên bố Match, các từ ngữ trong mô hình (ví dụ: phần trước ->) khai nhận dạng mới. Khi bạn sử dụng lại y trong mẫu của mình, bạn đang ẩn số nhận dạng trước y và tạo một số nhận dạng mới có cùng giá trị với điều bạn đang đối sánh, trong trường hợp này là số nhận dạng x. Nói cách khác, bạn luôn luôn so sánh giá trị của x với chính nó. Như những người khác đã lưu ý, điều này có thể được thực hiện tốt nhất với tuyên bố if.