F#编译器无法识别类型

dud*_*er4 1 f#

在这个片段中,当前(4.1)编译器抱怨它无法确定转换为使用哪个重载(可能需要类型注释),但它将s识别为字符串.为什么?

let wtf (list:string List) =  
  List.map (fun s -> System.Convert.ToInt32(s)) list
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 8

正如评论中所提到的,编译器对代码使用单次传递来确定类型.这意味着当它通过有问题的代码时,它将报告错误(例如,当它无法确定使用哪个重载时).如果稍后发现更多信息,则不使用附加信息.

这正是这里发生的事情.考虑:

let wtf (list:string List) =  
  List.map (fun s -> s) list
Run Code Online (Sandbox Code Playgroud)

在这里,sis 的类型string和一切正常.然而,检查时fun s -> s,编译器不知道的还以为类型sstring,它把它当作类型变量的值'a-它检查的功能类型'a -> 'a,后来统一'astring.回到你的案子:

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)