[英]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.