Inconsistent processing of a generic ParamArray argument in F #

Being seen in the context of this question , this seemingly inconsistent behavior can be reproduced in both F # 2.0 and F # 3.0 RC:

type Heterogeneous = static member Echo([<ParamArray>] args: Object[]) = args type Generic = static member Echo<'T>([<ParamArray>] args: 'T[]) = args 

Usage: Returns:

 Heterogeneous.Echo 0 // [|0|] OK Generic.Echo 0 // [|0|] OK Heterogeneous.Echo (0,1) // [|0; 1|] OK Generic.Echo (0,1) // [|0; 1|] OK Heterogeneous.Echo [|0|] // [|[|0|]|] OK? Generic.Echo [|0|] // [|0|] OOPS!! Heterogeneous.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK Generic.Echo ([|0|],[|1|])) // [|[|0|]; [|1|]|] OK 

Can someone explain if the observed behavior is a bug or function?

UPDATE: This response reports confirmation from the F # development team that the error currently occurs when processing generic type arguments with the ParamArray attribute.

+4
source share
1 answer

The case is a bit confusing because when you use an array as the actual argument for a parameter marked with a ParamArray , the language tries to interpret it as if you were passing the array to standard typed parameters of the array (therefore, it ignores the ParamArray attribute, if possible).

In your example, this is possible in the second case:

 Generic.Echo [|0|] 

The compiler reports that 'T is int , and therefore you pass int[] parameter of type int[] , and therefore the compiler ignores the ParamArray attribute, and the method simply gets an array containing 0 .

Otherwise, this is not possible:

 Heterogeneous.Echo [|0|] 

The method expects a parameter of type obj[] , and the argument type is int[] , so the two types cannot be unified (the key is that the compiler does not automatically convert int[] to obj[] ), since this is impossible, it considers the ParamArray attribute and trying to convert int[] to obj and pass it as a member of ParamArray - this is a conversion that the compiler can automatically perform, and therefore you get the result that you described.

If you called Heterogeneous.Echo with obj[] as an argument, it will behave similarly to Generic.Echo . For instance:

 Heterogeneous.Echo [| box 0 |] 

If you want to go into details, you can see section 14.4. F # language specification . However, the rules for overload resolution are quite complex, so I don't have an exact link that explains this behavior - just an unofficial explanation above.

+5
source

All Articles