繁体   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