在F#中对2D数组进行探查使编译器认为迭代值是对象类型。为什么?

问题描述:

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

I'm having trouble in this seemingly simple issue:

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 ,这有点奇怪。

The problem seems to be that F# thinks v is of type obj, which is kind of odd.

这是编译器错误还是我丢失了某些内容

Is this a compiler bug or am I missing something perfectly obvious?

谢谢

如果我们反映为类型 System.Int32 [,] ,它是 xs 的缩写,我们可能会观察到它仅实现非通用的 System.Collections。 IEnumerable 界面,所以在废止

If we reflect into type System.Int32[,], which xs is of, we may observe that it implements only non-generic System.Collections.IEnumerable interface, so after desugaring

for v in xs do...

转换为等效值

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

我们可以看到上面的 v 为什么是 obj -这是 System.Collections.IEnumerable.Current 属性。

we can see why v above is of type obj - this is the type of System.Collections.IEnumerable.Current property.

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

EDIT: However, if explicitly cast xs type of int[,] to seq<int>, like below:

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

v 现在的类型为 int ,编译器很高兴。

that is, v is now of type int and compiler is happy.