F#编译器无法识别类型

时间:2017-04-12 17:35:07

标签: f#

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

let wtf (list:string List) =  
  List.map (fun s -> System.Convert.ToInt32(s)) list

1 个答案:

答案 0 :(得分:8)

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

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

let wtf (list:string List) =  
  List.map (fun s -> s) list

此处,s的类型为string,一切正常。但是,在检查fun s -> s时,编译器还不知道s的类型是string,并且它将其视为类型变量'a的值 - 它会检查函数类型为'a -> 'a,稍后会将'astring统一起来。回到你的案子:

let wtf (list:string List) =  
  List.map (fun s -> System.Convert.ToInt32(s)) list

检查lambda时,编译器知道s类型为'a,但无法解决ToInt32的重载问题。它报告错误,跳过子表达式并继续(尽可能获得有用的IntelliSense),后来发现s实际上是string。这出现在IntelliSense中,但它不会撤消错误。

仅为了记录,避免这种情况的最佳方法是使用|>并首先输入list输入:

let awesome (list:string List) =  
  list |> List.map (fun s -> System.Convert.ToInt32(s))