7

为什么fail值会抛出异常?fine价值有效。如果我删除inline或转换'tfloat然后它工作。

[<Struct>]
type Test<'t> =
  val x: 't
  val y: 't
  new (x,y) = { x = x; y = y }

  static member inline (+) ((x,y), a: _ Test) = 0
  static member inline (-) ((x,y), a: _ Test) = 0

let a = 1.,2.
let b = Test(1.,2.)
let fine = a - b
let fail = a + b

错误信息:

未处理的异常:System.TypeInitializationException:'AdditionDynamicImplTable 3' threw an exception. ---> System.NotSupportedExcep tion: Dynamic invocation of op_Addition involving coercions is not supported. at Microsoft.FSharp.Core.LanguagePrimitives.dyn@2445[a,b,c](Type aty, Type bt y, Unit unitVar0) at Microsoft.FSharp.Core.LanguagePrimitives.AdditionDynamicImplTable3..cctor () 的类型初始化程序---内部异常堆栈跟踪结束---在 Microsoft.FSharp.Core.LanguagePrimitives.AdditionDynamic[T1,T2,TResult]( T1 x, T2 y) 在 C:\Users\olsv\Docume nts\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program 中的 .$Program.main@()。fs:line 14 按任意键继续。. .

4

1 回答 1

6

这看起来像是编译器中的一个错误——或者我遗漏了一些东西(请fsbugsmicrosoftdot处报告com)。由于某种原因,编译器无法内联对+运算符的调用(它似乎适用于-and/和自定义运算符,例如,但对于and+.失败)。+*

这意味着编译器实际上会生成如下内容:

// Inlined - returns zero directly
fine = 0; 

// Failed to inline - calls a version which used dynamic lookup
fail = LanguagePrimitives.AdditionDynamic
         <Tuple<double, double>, Test.Test<double>, double>(a, b);

AdditionDynamic方法使用一些内部表+在运行时找到这两种类型的实现。尽管您可以在那里注册您的类型,但它并没有真正的用处,因为调用会很慢。

我真的没有任何好的解决方法 - 如果您只需要一些基本数字类型( , 等)的运算符floatint那么最简单的选择可能是避免inline在此处使用并为特定类型定义(重载)运算符:

 static member (+) ((x:float,y:float), a: float Test) = x + y + a.x + a.y 

您也可以尝试使用全局运算符和实现不同重载的辅助类型的技巧,但我不确定这是否会有所帮助:例如,请参阅过去的问题

于 2013-04-19T11:19:12.897 回答