Array covariance in F #

Since .NET arrays are covariant, the following works in C #:

var strArray = new string[0]; object[] objArray = strArray; 

In F # given by the array, 'T[] , what would be the best way to convert it to obj[] without re-creating the array (e.g. Array.map box )? I use (box >> unbox) , but it feels (box >> unbox) .

+4
source share
3 answers
 box >> unbox 

seems like a good idea; O (1), and does the job, apparently.

Also consider that this CLR function is not used .;)

+3
source

According to Brian, there is nothing wrong with box >> unbox , except that the fact that the covariance of the array is inherently broken (for example, ([| "test" |] |> box |> unbox<obj[]>).[0] <- obj() will throw an ArrayTypeMismatchException when trying to make an assignment).

Instead, you will probably be better off treating string[] as obj seq , which is completely safe (although F # still requires boxing and decompression in F #, since F # does not support common co / contra-variance). Unfortunately, you lose random access if you go along this route.

+4
source

Brian's solution looks great to me, but do you really need array covariance?

If you have a function that accepts ISomething[] and wants to pass SomeSomething[] , then you will need it, but if the function only reads values โ€‹โ€‹of the ISomething type from the array (which allows covariance) then you can use the hash type and write a function, which accepts #ISomething[] . (Assuming you can change the function, of course!)

Thus, the function can work with an array of any elements that implement ISomething , and you do not need the covariance of the array when called. Here is an example:

 type A() = interface IDisposable with member x.Dispose() = printfn "gone" // Disposes the first element from an array let disposeFirst (a:#IDisposable[]) = a.[0].Dispose() // Call 'disposeFirst' with 'A[]' as an argument let aa = [| new A(); new A() |] disposeFirst aa 

It seems to me that the main reason for array covariance in .NET is that it was needed at a time when generics did not exist, but it seems that F # can live without this function just fine.

+3
source

All Articles