I suspect that I am missing something very obvious here but this doesn’t work:
let t = Array2D.create 1 1 1.0
for x in t do printfn "%f" x;;
It fails with
error FS0001: The type ‘obj’ is not compatible with any of the types float,float32,decimal, arising from the use of a printf-style format string
Interestingly using printf "%A" or "%O" prints the expected values which suggests to me that the problem is with the type inference
The corresponding code for a 1D array works fine
let t = Array.create 1 1.0
for x in t do printfn "%f" x;;
For reference this is on version 2.0 (both interactive and compiler) running on the latest mono
In .NET, a 1D array implicitly implements IList, which means it also implements (by inheritance)
IEnumerable<T>. So, when you run:the F# compiler emits code which gets an implementation of
IEnumerable<T>(seq<T>in F#) fromt, then iterates over it. Since it’s able to get anIEnumerable<T>from the array,xwill have typeT.On the other hand, multi-dimensional arrays (2d, 3d, etc.) only implement
IEnumerable(notIEnumerable<T>) so the F# compiler infers the type ofxasSystem.Object(orobj, in F#).There are two solutions for what you want:
Cast each individual value within the loop, before printing it:
Or, use Seq.cast to create and iterate over a strongly-typed enumerator: