F# 中的二维数组上的 Foreach 使编译器认为迭代值是对象类型。为什么?

Foreach over a 2D Array in F# makes the compiler think the iterated values are of type object. Why?

我在这个看似简单的问题上遇到了麻烦:

let xs = Array2D.init 3 3 (fun j i -> j*3 + i)
printfn "%O" (xs.GetType()) // prints System.Int32[,]

for v in xs do
    printfn "%d" v // <- this gives a compiler error. why should it?

问题似乎是 F# 认为 v 是类型 obj,这有点奇怪。

这是编译器错误还是我遗漏了一些非常明显的东西?

谢谢

如果我们反思 System.Int32[,] 类型,xs 属于它,我们可能会观察到它只实现了非泛型 System.Collections.IEnumerable 接口,所以在

脱糖之后
for v in xs do...

转化为等价物

let xe = xs.GetEnumerator()
while xe.MoveNext() do
    let v = xe.Current
    ...

我们可以看出为什么上面的 vobj 类型——这是 System.Collections.IEnumerable.Current 属性.

的类型

编辑:但是,如果将 int[,]xs 类型显式转换为 seq<int>,如下所示:

for v in Seq.cast<int> xs do
    printfn "%d" v

也就是说,v 现在属于 int 类型,编译器很满意。