Inline plus operator in struct throws an exception (F#)
exception, f#, operators, struct
Solution
This looks like a bug in the compiler - or I am missing something (please report it at `fsbugs` at `microsoft` dot `com`). For some reason, the compiler fails to inline the call to the `+` operator (it seems to work for `-` and `/` and for custom operators like `+.`, but fails for `+` and `*`).
This means that the compiler actually generates something like:
// 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);
The `AdditionDynamic` method uses some internal table to find an implementation of `+` for the two types at runtime. Although you could register your type there, it would not really be useful, because the invocation would be slow.
I do not really have any nice workaround for this - if you need the operator only for some basic numeric types (`float`, `int`, etc.) then the easiest option might be to just avoid using `inline` here and define (an overloaded) operator for the specific types:
static member (+) ((x:float,y:float), a: float Test) = x + y + a.x + a.y
You can also try the trick with global operator and a helper type that implements the different overloads, but I'm not sure if that's going to help: see, for example, this past question.
Problem
Why does the `fail` value throw an exception? `fine` value works. If I remove `inline` or if I convert `'t` into `float` then it works. ``` [<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 ``` error message: Unhandled Exception: System.TypeInitializationException: The type initializer fo r '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.AdditionDynamicImplTable`3..cctor () --- End of inner exception stack trace --- at Microsoft.FSharp.Core.LanguagePrimitives.AdditionDynamic[T1,T2,TResult](T1 x, T2 y) at .$Program.main@() in C:\Users\olsv\Docume nts\Visual Studio 2012\Projects\ConsoleApplication1\ConsoleApplication1\Program. fs:line 14 Press any key to continue . . .