Array covariance in F#

为君一笑 提交于 2019-12-07 05:24:11

问题


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

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

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


回答1:


box >> unbox

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

Consider also not using this CLR mis-feature. ;)




回答2:


As Brian says, there's nothing wrong with box >> unbox, other that the fact that array covariance is inherently broken (e.g. ([| "test" |] |> box |> unbox<obj[]>).[0] <- obj() will throw an ArrayTypeMismatchException when trying to perform the assignment).

Instead, you would probably be better off treating a string[] as an obj seq, which is perfectly safe (although it still requires boxing and unboxing in F# since F# doesn't support generic co/contra-variance). Unfortunately, you do lose random access if you go this route.




回答3:


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

If you have a function that takes ISomething[] and want to pass it SomeSomething[] then you need it, but if the function only reads values of type ISomething from the array (which is what the covariance allows), then you could use hash-type and write a function that takes #ISomething[]. (Assuming that you can modify the function, of course!)

This way, the function can work on array of any elements that implement ISomething and you don't need array covariance when calling it. 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 the time when generics did not exist, but it seems that F# can live without this feature just fine.



来源:https://stackoverflow.com/questions/7339013/array-covariance-in-f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!