How to correctly overload global (+) and (*) without breaking support for other types

I imported a vector math library and would like to add my own (*) and (+) operators, while preserving the existing operators for the base int and float.

I tried the following:

let inline (*) (x : float) (y : Vector) = y.Multiply(x) let inline (*) (x : Vector) (y : float) = x.Multiply(y) let inline (+) (x : Vector) (y : Vector) = x.Add(y) 

There are two problems:

  • It seems int + int and int * int are being removed, and
  • The second line (which is intended to complete commutativity) does not compile because it is a "duplicate definition".

How can I define some commutative operators in my imported Vector type and also not lose these operations for int and floats?

(I want to be able to write general code elsewhere using * and +, without specifying restrictions like float / Vector / int).

+4
source share
2 answers

If you can change the source code of the library, it’s easier to add a few overloads through type extensions:

 type Vector with static member (*) (x : Vector) (y : float) = x.Multiply(y) static member (+) (x : Vector) (y : Vector) = x.Add(y) 

However, if the first operand is of a primitive type (for example, your first example), permission overloading no longer works.

In any case, you can use element overloading and extend restrictions to the built-in function:

 type VectorOverloadsMult = | VectorOverloadsMult static member (?<-) (VectorOverloadsMult, x: float, y: Vector) = y.Multiply(x) static member (?<-) (VectorOverloadsMult, x: Vector, y: float) = x.Multiply(y) static member inline (?<-) (VectorOverloadsMult, x, y) = x * y let inline (*) xy = (?<-) VectorOverloadsMult xy 

This works for existing types with (*) , since we store them in the last static member. You can do the same for the (+) operator.

 let v: Vector = ... // Declare a Vector value let a = 2.0 * v let b = v * 2.0 let c = 2 * 3 let d = 2.0 * 3.0 

This method works even if you cannot change the type of Vector .

+9
source

You need to define the operators inside your type - i.e.

 type Vector = .... static member (+) (x : Vector) (y : Vector) = x.Add(y) 

and etc.

Then everything will work as you expect

+3
source

All Articles