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