簡體   English   中英

F#顯式成員約束:無法廣義化類型變量^ T,因為它將逃避其范圍

[英]F# explicit member constraints: The type variable ^T could not be generalized because it would escape its scope

我正在嘗試在F#中使用顯式成員約束 文檔說“ F#支持公共語言運行時支持的完整約束集”,但是如果我實際上用這樣的顯式約束(例如以下內容)編譯一個類,則會出現非常奇怪的錯誤。

type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)> =
    member this.F a b = a + b

報告

錯誤FS0670:此代碼不夠通用。 當^ T:(靜態成員(+):^ T * ^ T-> ^ T)時,類型變量^ T不能被泛化,因為它將逃避其范圍。

並在定義member this.F的位置報告。 這是什么意思? 相關范圍是什么?

該語言支持多種方法來執行此類工作。 可以在StackOverflow上找到一個不錯的探索,但是我還沒有清楚地解釋為什么不允許這種特殊的通用約束“轉義”。

成員約束需要靜態解析的類型參數。 但是類型上不允許靜態解析的類型參數(如您的示例所示),僅適用於內聯函數和內聯方法。

潛在的問題可能是整個類型不能內聯。

另請參閱: http : //msdn.microsoft.com/en-us/library/dd548046.aspx

如果您使用這樣的內聯成員:

type MyType() =
    member inline this.F a b = a + b

a和b的類型將被自動限制。

您需要標記成員inline (如果要強制參數為^T類型,請添加類型注釋):

type MyType<'T when ^T: (static member ( + ) : ^T * ^T -> ^T)>() =   
    member inline this.F (a:^T) (b:^T)  = a + b

我還添加了一個構造函數,以便您可以實際調用該方法:

MyType().F 1 2

正如其他人指出的那樣,幾乎不需要手動寫出顯式成員約束,因為通常可以推斷出它們。 此外,在這種情況下,沒有理由將約束置於類型而不是方法上,並且通過靜態解析的類型變量對類型進行參數化不是慣用的。

F#規范:

^ ident形式的類型是靜態解析的變量類型。 將創建一個新的類型推斷變量,並將其添加到類型推斷環境中(請參見第14.6節)。 用一個屬性標記該類型變量,該屬性指示除非在內聯定義中(參見第14.7節),否則不能對其進行一般化,同樣,通過類型推斷方程式對其進行等同運算的任何類型變量也可以類似地不進行一般化。

http://research.microsoft.com/zh-cn/um/cambridge/projects/fsharp/manual/spec.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM