devoured elysium
devoured elysium

Reputation: 105077

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

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?

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?

Thanks

Upvotes: 3

Views: 548

Answers (1)

Gene Belitski
Gene Belitski

Reputation: 10350

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...

into its equivalent

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

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

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

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

Upvotes: 9

Related Questions