F # - How to extend a type with get_Zero so that I can use the existing type as a whole?

I am trying to do the following:

let cx = 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 for type extensions, from https://msdn.microsoft.com/en-us/library/dd233211.aspx , and try the following:

 module ComplexExtension = let cx = 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 am still getting this error.

Is it possible to extend a type using the get_Zero operator? Or do I need to create my own wrapper type around System.Numerics.Complex and override all statements if I want it to perform other actions that perform complex numbers?

+5
f # complex-numbers
Oct 28 '15 at 23:35
source share
2 answers

List.sum uses static item restrictions. Static member constraints are not considered in extension methods, so this is not an option.

A wrapper of all complex type is an option, but it overflows, if it is just a specific call, you have many ways to calculate the sum with a few keystrokes, you can use fold , as shown in another answer. Alternatively, you can use List.reduce (+) if you are sure that there will always be at least one element in the list.

This may be fixed in a future version of F #, but the problem is that the static restrictions of members do not work with fields if they do not have a getter. However, in F # lib they can "emulate" those elements for existing types, they usually do this with primitive types , otherwise it would not work with int , float , since they also do not have this member.

I'm not sure that the fact that Complex defined in System.Numerics was the reason not to implement it that way, or maybe they just forgot it. In either case, you can open the problem or send a transfer request to fix it.

Finally, another option, if you still want to use it in a generic way, is to override the sum function. For example, the sum function (here the source ) from the last F # + will work fine (it had the same problem, but it was very easy to fix, in fact it was a mistake) with almost all numeric types, including Complex and most third-party numeric types since it is a backup mechanism that relies on some conversions when the type does not have a get_Zero member.

+4
Oct 29 '15 at 1:02
source share

List.sum does not recognize Zero , defined as an extension. It must be part of this type.

Use List.fold :

 let sum = [c 1.0; c 2.0] |> List.fold (+) Complex.Zero 

BTW System.Numerics.Complex actually has a static Zero , but this is a field, not a property.

+1
Oct 29 '15 at 0:02
source share



All Articles