2016-06-18 20 views
9

Tôi đã cố gắng để xác định một trường hợp tổng quát hơn cho (!) Điều hành như sau,F # gọi hàm inline với những kiểu

let inline (!) (cell : ^a) = 
    (^a : (member Value : ^b) cell) 

Vì vậy, nó không chỉ làm việc cho ref loại, nhưng bất kỳ loại với một Value thành viên.

> !(ref 10) ;; 
val it : int = 10 

> !(lazy 5) ;; 
val it : int = 5 

Nhưng vấn đề nảy sinh khi tôi cố gắng để áp dụng nó vào một loại với những kiểu,

> let getValue (c : 'a ref) = !c ;; 

    let getValue (c : 'a ref) = !c ;; 
    ------------------^^ 

C:\Users\User\AppData\Local\Temp\stdin(6,19): warning FS0064: This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'obj'. 

val getValue : c:obj ref -> obj 

trong khi nó hoạt động tốt nếu tôi mở rộng chức năng inline.

> let getValue (c : 'a ref) = c.Value ;; 

val getValue : c:'a ref -> 'a 

Bất cứ ai cũng biết tại sao điều này xảy ra? Cảm ơn.

Trả lời

5

Vì chức năng getValue của bạn không trực tuyến, các ràng buộc sẽ không hoạt động.

Vấn đề là hệ thống kiểu .NET không thể lưu trữ loại ràng buộc mà F # có thể sử dụng trong inline.

Kết quả là, khi bạn có chức năng không trực tuyến sử dụng hàm nội tuyến theo cách này, bạn sẽ gặp lỗi.

+0

Phiên bản thứ hai của 'getValue' chỉ là bản mở rộng cũ của phiên bản cũ, tôi biết tôi có thể thiếu thứ gì đó ở đây nhưng tôi vẫn không thể thấy cách trước đây giới thiệu nhiều ràng buộc kiểu hơn so với phiên bản sau. không chụp. – Doaz

+0

Tôi nghĩ rằng các ràng buộc trên 'getValue' là một siêu của các ràng buộc trên'! '. Khi các lỗi của các ràng buộc trên 'getValue' yêu cầu nội dòng, nó không thể là một hàm không phải inline –

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