F# function changes type when compiled with standalone switch and referenced from another project

僤鯓⒐⒋嵵緔 提交于 2019-12-11 03:33:41

问题


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

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