为什么此示例中存在类型推断错误

Pau*_*zak 3 f#

我在这个片段中收到"根据此程序点之前的信息查找不确定类型的对象"错误:

let a = [|"a"; "bb"|]
let n = Array.mapi (fun i x -> (i * x.Length)) a
Run Code Online (Sandbox Code Playgroud)

这有什么问题?当我将光标悬停在其上方时,Visual Studio F#Interactive正确地将x的类型显示为字符串.为什么我要写:

let a = [|"a"; "bb"|]
let n = Array.mapi (fun i (x:string) -> (i * x.Length)) a
Run Code Online (Sandbox Code Playgroud)

编译成功?

byt*_*ter 6

类型检查器从左到右工作.由于这个原因,编译器没有足够的信息来推断出正确的类型x.

克服这个问题的最简单方法是a在开头放置:

let n = a |> Array.mapi (fun i x -> (i * x.Length))
Run Code Online (Sandbox Code Playgroud)

编译器将知道它a具有类型string [],因此xstring.

另一种方法是使用静态函数:

let n = Array.mapi (fun i x -> (i * String.length x)) a
Run Code Online (Sandbox Code Playgroud)

String.length取a string,因此string成为推断类型x.