Tóm tắt Sự cốLàm cách nào để chuyển đổi hoàn toàn thành các loại siêu phổ biến trong các kết hợp mẫu F #?
Tại thời điểm này khi sử dụng f # Tôi phải ép buộc một cách rõ ràng giá trị cho các loại mẹ của loại của nó để có được mô hình phù hợp với biểu thức để gõ kiểm tra một cách chính xác. Tôi sẽ lý tưởng như một cách thức làm việc.
Ví dụ
Giả sử tôi có một số lớp hệ thống cấp bậc:
type Foo() =
abstract member Value : unit -> string
type A (i:int) =
inherit Foo()
override this.Value() = i.ToString()
type B (s:string) =
inherit Foo()
override this.Value() = s
Lý tưởng nhất, và trong một số ngôn ngữ lập trình trong bình thường, tôi sẽ viết tương đương với các nội dung sau:
let bar (i:int) : Foo =
match i with
| 1 -> B "one"
| _ -> A i
Tuy nhiên điều này không đánh máy kiểm tra chính xác, cho tôi lỗi, "Biểu hiện này được dự kiến sẽ có loại Foo nhưng cô ấy e có loại B ". Tôi không hiểu tại sao trình biên dịch không có đủ thông tin để suy ra một loại siêu phổ biến cho biểu thức khớp và sau đó kiểm tra xem loại siêu phổ biến là 'Foo' hay không.
Hiện nay tôi buộc phải cung cấp một sự ép buộc rõ ràng cho mọi trường hợp trong mô hình phù hợp:
let bar2 (i:int) : Foo =
match i with
| 1 -> (B "one") :> Foo
| _ -> (A i) :> Foo
Tôi muốn tránh điều này.
Ghi chú Hơn nữa
- Trực giác cho thấy rằng đây là một kết quả của một vấn đề tổng quát hơn. Tôi đã có thể nghĩ rằng mặc dù một cái gì đó phổ biến như phù hợp với mô hình, hoặc nếu báo cáo mà cũng thể hiện cùng một tài sản, sẽ có một loại kiểm tra quy tắc để giải thích cho các loại siêu phổ biến.
- Trước khi bất cứ ai gợi ý - Tôi đánh giá cao nếu A hoặc B là Biểu thức đối tượng thì điều này sẽ hiệu quả, nhưng ví dụ thực sự của tôi là tạo các thể hiện của các lớp C# nơi chúng là các lớp bình thường.
- Có cách nào để tôi khai báo hàm để chuyển đổi các loại ngầm định, ví dụ như scala có, vì vậy tôi có thể áp dụng chuyển đổi tự động cho mô-đun mà tôi đang tạo thế hệ này không?
Cảm ơn bạn đã giúp đỡ về vấn đề này.
Lý do trình kiểm tra loại không thực hiện bất kỳ hành vi phạm tội nào với các kiểu dẫn xuất là trước tiên nó sẽ làm cho bước kiểm tra kiểu phức tạp hơn và thứ hai nó cho phép bạn giới thiệu các lỗi tinh vi. Ví dụ: hãy xem xét các điều sau: khớp với i với | 1 -> B ("một") | 2 -> "stuff" Vâng, cả hai System.String và B chia sẻ chung loại cơ sở System.Object, do đó kết quả của biểu thức khớp đó là loại obj. Đó là 99,9% không phải những gì bạn muốn. –
Đúng, mặc dù trong trường hợp cụ thể mà OP hỏi, anh ta đã khai báo kiểu trả về hàm là ': Foo', vì vậy tôi nghĩ có lẽ sẽ không hoàn toàn vô lý đối với người trợ giúp để sử dụng nó như là một mức thấp nhất bị ràng buộc hoặc một cái gì đó. Tuy nhiên, tôi đã không suy nghĩ qua tất cả các hàm ý của điều đó. – Brian
Tôi nghĩ rằng 'x:> _' đọc tốt hơn' upcast x', nhưng có lẽ đó chỉ là tôi. Các chi nhánh của trận đấu không xếp hàng là tốt, mặc dù. – kvb