Visual Studio 2012试用版中的F#IntelliSense

Shr*_*roy 1 f# type-inference

我一直遇到以下问题:

(System.Console.ReadLine ()).Split [|'('; ')'|]
|> Array.filter (fun s -> not (System.String.IsNullOrEmpty (s)))
|> Array.map (fun s -> s.Split [|','|])
|> Array.map (fun s -> Array.map (fun t -> t.Trim ()) s) (* t.Trim () is underlined with a red squiggly line *)
|> [MORE CODE]
Run Code Online (Sandbox Code Playgroud)

与红色波浪线相关的错误是:

Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved.

但是当鼠标指针悬停时t,IntelliSense正确地说明了这t一点type string.

我可以通过编写来绕过错误fun (t : string) -> [CODE],但我想知道为什么当Visual Studio已经正确检测到变量的类型时,它会绘制出波浪线.这是试验版本中的一个简单错误,还是我误解了F#的类型推理?

在此先感谢您的回复.

pad*_*pad 7

F#intellisense和F#类型检查器之间存在一些差距.

类型检查器按顺序从左到右工作.您可以修改问题:

fun s -> Array.map (fun t -> t.Trim()) s
Run Code Online (Sandbox Code Playgroud)

fun s -> s |> Array.map (fun t -> t.Trim())
Run Code Online (Sandbox Code Playgroud)

由于类型s在使用之前是可用的Array.map,因此类型检查器能够推断出类型t.

备注:

使用实例方法时通常会发生此错误.您可以使用带有额外类型注释和重构的静态函数替换这些方法,以使您的代码更具可组合性:

let split arr (s: string) = s.Split arr
let trim (s: string) = s.Trim()

System.Console.ReadLine()
|> split [|'('; ')'|]
|> Array.filter (not << System.String.IsNullOrEmpty)
|> Array.map (split [|','|])
|> Array.map (Array.map trim)
Run Code Online (Sandbox Code Playgroud)

  • 另外 - 你可以使用`StringSplitOptions.RemoveEmptyEntries`来避免`filter`步骤 (2认同)