问题
In a Visual Studio project for an F# library I have defined a function as
let inline Estimate (s : ^a seq) (f : float) (w : int) : float * float = ..
The type of Estimate
is
val Estimate : s:seq<'a> -> f:float -> w:int -> float*float
Calling Estimate
from a script within that project works as expected.
Now if I compile the project with the --standalone
switch and reference the output DLL from another project, Estimate
is shown to be
Estimate<'a,'a>(s: Collections.Generic.IEnumerabls<'a>, f: float, w:int) : float*float
i.e. it some reason now takes tuple arguments. Thus the following does not work
let q, p = EstimationQuality.Estimate x f 1 // This value is not a function and cannot be applied
but calling it with tuple parameters works fine
let q, p = EstimationQuality.Estimate (x, f, 1) // No problem.
What's wrong here? Is it a bug in the compiler?
EDIT:
Digging a little deeper, it appears that the problem is linked with the use of LanguagePrimitives.GenericZero
.
While the problem actually compiles with the tuple parameter call, i get a runtime error when Estimate
is called.
An unhandled exception of type 'System.TypeInitializationException' occurred in LibraryTest.dll
Additional information: The type initializer for 'GenericZeroDynamicImplTable`1' threw an exception.
回答1:
Compiling an F# DLL which is intended to be used from F#, with the standalone switch is not a good idea.
Why? Because all the F# metadata is lost since the whole set of F# types are included in your DLL so those types get a different identity from the types of the F# application that call your DLL or fsi.
The caller assembly uses the types in Fsharp.Core.dll which now are not the same as the ones used in your standalone compiled DLL.
That's why you see the tupled arguments, as seen from C# which doesn't understand F# metadata at all.
Generic inline functions using static constraints break as well since they need the metadata to inline at the call site.
Compiling also the caller assembly as standalone would make things worse, then you will have 3 sets of Fsharp types with different identities.
I think the standalone switch is fine when used only in the 'end-user' application.
来源:https://stackoverflow.com/questions/28098961/f-function-changes-type-when-compiled-with-standalone-switch-and-referenced-fro