在这个片段中,当前(4.1)编译器抱怨它无法确定转换为使用哪个重载(可能需要类型注释),但它将s识别为字符串.为什么?
let wtf (list:string List) =
List.map (fun s -> System.Convert.ToInt32(s)) list
Run Code Online (Sandbox Code Playgroud)
正如评论中所提到的,编译器对代码使用单次传递来确定类型.这意味着当它通过有问题的代码时,它将报告错误(例如,当它无法确定使用哪个重载时).如果稍后发现更多信息,则不使用附加信息.
这正是这里发生的事情.考虑:
let wtf (list:string List) =
List.map (fun s -> s) list
Run Code Online (Sandbox Code Playgroud)
在这里,sis 的类型string和一切正常.然而,检查时fun s -> s,编译器不知道的还以为类型s是string,它把它当作类型变量的值'a-它检查的功能类型'a -> 'a,后来统一'a用string.回到你的案子:
let wtf (list:string List) =
List.map (fun s -> System.Convert.ToInt32(s)) list
Run Code Online (Sandbox Code Playgroud)
检查lambda时,编译器知道s是类型的'a,它无法解决重载ToInt32.它报告错误,跳过子表达式并继续(以获得尽可能有用的IntelliSense),然后它会发现s实际上是这样string.这出现在IntelliSense中,但它不会撤消错误.
只是为了记录在案,以避免这种情况的最好方法是使用|>,并把list第一个输入:
let awesome (list:string List) =
list |> List.map (fun s -> System.Convert.ToInt32(s))
Run Code Online (Sandbox Code Playgroud)