Lý do tại sao bạn đang nhìn thấy hành vi này là bởi vì F # không định nghĩa (~%)
với các ràng buộc tĩnh giống như hầu hết các nhà khai thác cấp cao nhất. Nó được định nghĩa là hàm Quotations.Expr<'a> -> 'a
. Do đó, hàm (~%)
(là bí danh cho op_Splice
) bạn đã xác định trên loại T
không được giải quyết bằng cách sử dụng toán tử (~%)
cấp cao nhất.
Bạn có thể thấy điều này bởi sự tương tác FSI sau:
> <@ (~%) @>;;
<@ (~%) @>;;
^^^^^^^^^^
C:\Users\Stephen\AppData\Local\Temp\stdin(5,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : Expr<(Expr<'_a> -> '_a)>
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
Vì vậy, nếu chúng ta xác định lại cấp cao nhất (~%)
điều hành như sau, sau đó dụ của bạn sẽ biên dịch mà không có lỗi:
let inline (~%) (x : ^a) = (^a : (static member op_Splice : ^a -> 'b) (x))
nhưng lưu ý rằng việc trích dẫn báo giá sẽ không còn hoạt động:
let x = <@ 3 @>
<@ %x @>
----^
error FS0001: The type 'Expr<int>' does not support the operator '~%'
đó là bởi vì định nghĩa ban đầu của (~%)
được xử lý đặc biệt bởi trình biên dịch để nối báo giá. Thật vậy, bạn có thể see trong các chữ ký Expr
và Expr<'T>
rằng các loại đó không xác định bất kỳ toán tử nào cả, hãy để một mình op_Splice
.
Bạn có thể xem các kết quả tương tự với các toán tử mã hóa &&
và ||
. Có thể được định nghĩa lại (ánh xạ tới op_BooleanAnd
và op_BooleanOr
), nhưng trừ khi chúng là, chúng được xử lý đặc biệt bởi trình biên dịch.
Nguồn
2012-05-06 17:16:46