F# 函数在使用独立开关编译并从另一个项目引用时更改类型
F# function changes type when compiled with standalone switch and referenced from another project
在 F# 库的 Visual Studio 项目中,我将一个函数定义为
let inline Estimate (s : ^a seq) (f : float) (w : int) : float * float = ..
Estimate
的类型是
val Estimate : s:seq<'a> -> f:float -> w:int -> float*float
从该项目中的脚本调用 Estimate
按预期工作。
现在,如果我使用 --standalone
开关编译项目并引用另一个项目的输出 DLL,Estimate
显示为
Estimate<'a,'a>(s: Collections.Generic.IEnumerabls<'a>, f: float, w:int) : float*float
即现在出于某种原因需要元组参数。
因此以下内容不起作用
let q, p = EstimationQuality.Estimate x f 1 // This value is not a function and cannot be applied
但使用元组参数调用它工作正常
let q, p = EstimationQuality.Estimate (x, f, 1) // No problem.
这是怎么回事?它是编译器中的错误吗?
编辑:
再深入一点,问题似乎与 LanguagePrimitives.GenericZero
.
的使用有关
虽然问题实际上是通过元组参数调用编译的,但在调用 Estimate
时出现运行时错误。
An unhandled exception of type 'System.TypeInitializationException'
occurred in LibraryTest.dll
Additional information: The type initializer for
'GenericZeroDynamicImplTable`1' threw an exception.
使用独立开关编译旨在从 F# 使用的 F# DLL 不是一个好主意。
为什么?因为所有 F# 元数据都丢失了,因为整个 F# 类型集都包含在您的 DLL 中,所以这些类型与调用您的 DLL 或 fsi 的 F# 应用程序的类型获得不同的标识。
调用方程序集使用 Fsharp.Core.dll 中的类型,现在与独立编译的 DLL 中使用的类型不同。
这就是您看到元组参数的原因,正如 C# 所见,它根本不理解 F# 元数据。
使用静态约束的通用内联函数也会中断,因为它们需要元数据在调用站点内联。
将调用程序集也编译为独立程序会使事情变得更糟,然后您将拥有 3 组具有不同标识的 Fsharp 类型。
我认为独立开关仅在 'end-user' 应用程序中使用时很好。
在 F# 库的 Visual Studio 项目中,我将一个函数定义为
let inline Estimate (s : ^a seq) (f : float) (w : int) : float * float = ..
Estimate
的类型是
val Estimate : s:seq<'a> -> f:float -> w:int -> float*float
从该项目中的脚本调用 Estimate
按预期工作。
现在,如果我使用 --standalone
开关编译项目并引用另一个项目的输出 DLL,Estimate
显示为
Estimate<'a,'a>(s: Collections.Generic.IEnumerabls<'a>, f: float, w:int) : float*float
即现在出于某种原因需要元组参数。 因此以下内容不起作用
let q, p = EstimationQuality.Estimate x f 1 // This value is not a function and cannot be applied
但使用元组参数调用它工作正常
let q, p = EstimationQuality.Estimate (x, f, 1) // No problem.
这是怎么回事?它是编译器中的错误吗?
编辑:
再深入一点,问题似乎与 LanguagePrimitives.GenericZero
.
虽然问题实际上是通过元组参数调用编译的,但在调用 Estimate
时出现运行时错误。
An unhandled exception of type 'System.TypeInitializationException' occurred in LibraryTest.dll
Additional information: The type initializer for 'GenericZeroDynamicImplTable`1' threw an exception.
使用独立开关编译旨在从 F# 使用的 F# DLL 不是一个好主意。
为什么?因为所有 F# 元数据都丢失了,因为整个 F# 类型集都包含在您的 DLL 中,所以这些类型与调用您的 DLL 或 fsi 的 F# 应用程序的类型获得不同的标识。
调用方程序集使用 Fsharp.Core.dll 中的类型,现在与独立编译的 DLL 中使用的类型不同。
这就是您看到元组参数的原因,正如 C# 所见,它根本不理解 F# 元数据。
使用静态约束的通用内联函数也会中断,因为它们需要元数据在调用站点内联。
将调用程序集也编译为独立程序会使事情变得更糟,然后您将拥有 3 组具有不同标识的 Fsharp 类型。
我认为独立开关仅在 'end-user' 应用程序中使用时很好。