I attempt the following:
let c x = System.Numerics.Complex(x, 0.0)
let sum = [c 1.0; c 2.0] |> List.sum
But I get this error:
The type 'System.Numerics.Complex' does not support the operator 'get_Zero'
I read the rules on type extensions, from https://msdn.microsoft.com/en-us/library/dd233211.aspx, and try to do the following:
module ComplexExtension =
let c x = System.Numerics.Complex(x, 0.0)
type System.Numerics.Complex with
// I also tried a bunch of other ways of writing these
// as static or instance members, but nothing worked
static member Zero = c 0.0
static member One = c 1.0
open ComplexExtension
let sum = [c 1.0; c 2.0] |> List.sum
I still get that error.
Is it possible to extend a type with the get_Zero operator? Or do I have to create my own wrapper type around System.Numerics.Complex
and override all the operators if I want it to do the other things that complex numbers do?
List.sum
uses static member constraints. Static member constraints don't look into extensions methods so that's not an option.
Wrapping the whole complex type is an option but it's overkill, if it is just a specific call you have many ways to compute the sum with a few more keystrokes, you can use a fold
as shown on the other answer. Alternatively you can use List.reduce (+)
if you are sure that the list will always have at least one element.
This might be possible to get fixed in a future version of F# but the problem is that static member constraints don't work with fields, unless they have a getter. However in the F# lib they can "emulate" those members for existing types, they do it normally with primitive types otherwise it wouldn't work with int
, float
, since they don't have that member either.
I'm not sure if the fact that Complex
is defined in System.Numerics
was the reason not to implement it this way, or may be they just forgot it. In any case you can open an issue or submit a pull request to get it fixed.
Finally another option if you still want to use it in a generic way is to redefine the sum
function. For instance the sum
function (here's the source) from the latest F#+ version will work fine (it had the same problem but was very easy to fix, actually it was a bug) with practically all numeric types, including Complex
and most third party numeric types because it has a fallback mechanism which relies in some conversions when the type doesn't have a get_Zero
member.
List.sum
doesn't recognize a Zero
defined as extension. It must be part of the type.
Use List.fold
instead:
let sum = [c 1.0; c 2.0] |> List.fold (+) Complex.Zero
BTW System.Numerics.Complex
actually has a static Zero
, but it's a field, not a property.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With