Reputation: 570
How can basic operators like (+, -, *) be overloaded without overwriting their existing definitions? Reading some of the other threads on this topic I couldn't get a sense of what to do. Specifically, I am looking to define matrix operations directly on Array2D types. MathNet.Numerics somehow manages to do it for its Matrix and Vector types but not sure how. Defining regular functions instead of using operators completely fubars logic in linear algebra heavy applications.
type Array() =
static member (+) (A : float[,], B : float[,]) =
let r = A.GetLength 0
let c = A.GetLength 1
let C = Array2D.create r c 0.
for i in 0..r-1 do
for j in 0..c-1 do
C.[i, j] <- A.[i, j] + B.[i, j]
C
let a1 = Array2D.create 4 4 1.
let a2 = Array2D.create 4 4 1.
let a3 = a1 + a2 // type float[,] does not support the operator '+'
let y = 2 + 3 // don't want this overridden by something like a 'let inline...'
Upvotes: 1
Views: 123
Reputation: 13577
MathNet.Numerics shouldn't have much problem doing that if they provide operators for their own types, as part of their definition.
What you're trying to do is to provide an operator using an extension method - I don't think that's currently possible.
The easiest way out is to provide a slightly different operator, let's say +.
, so that there's no clashing, but the code still remains fairly easy to follow. This is what OCaml does to differentiate between int and float operators for instance (and F# gives you much room in picking symbols for custom operators).
let inline (+.) (A: float[,]) (B: float[,]) =
...
let a3 = a1 +. a2
There are other solutions - you could use a single case union to wrap the 2D arrays and define the operator as a member of that type, or you could make use of SRTPs to patch the operator onto an existing type and have it inlined at compile time, but going that way would also obscure the logic in one way or another.
Upvotes: 4