簡體   English   中英

在Math.Max上進行F#類型推斷

[英]F# Type inference on Math.Max

如果編譯器已經推斷出輸入參數的類型,為什么不選擇正確版本的重載方法。

在此示例中,當類型已正確推斷出要比較的元素時,為什么不能選擇要使用的正確Math.Max:

let listMax = 
    List.map2 (fun l r -> Math.Max(l,r)) [2;4] [5;3]       //compile error 
let listMax2 = 
    List.map2 (fun (l:int) r -> Math.Max(l,r)) [2;4] [5;3] //no compile error    

當然,在這種情況下,您可以只使用max函數,但是還有許多其他方法沒有本機等效方法。

正如@Gos正確指出的那樣,在這種情況下,使用管道運算符會有所幫助。 原因是類型推斷從左到右起作用-因此,如果使用管道運算符,它將知道輸入之一是一個整數列表,並在此基礎上選擇Math.Max的正確重載。

編譯器執行重載解析或要在對象上調用成員時(例如,如果要在map函數中執行l.Foo()通常需要知道類型-因為在這種情況下,它需要知道確切的類型是什么。

F#還定義了自己的基本數學函數版本,可以更好地進行類型推斷。 因此,您可以用max函數替換Math.Max (也可以將其直接傳遞給map2 ):

List.map2 max [2;4] [5;3] 

這樣效果更好,因為F#不需要執行重載解析(該函數不會重載)。 它只是跟蹤一個特殊的通用約束 ,該約束在以后得到滿足和解決。

我無法告訴您原因,但是我發現管道運算符通常有助於鍵入推斷:

let listMax = 
    [5;3] |> List.map2 (fun l r -> Math.Max(l,r)) [2;4]

暫無
暫無

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

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