I'm writing a tiny matrix library (mostly wrapper methods) in F#, and have a problem regarding overloading of static operator methods, with F# picking an overload which I did not intend it to.
I have a module where I've defined the right-multiplication of a matrix with a vector:
[<AutoOpen>]
module MatrixOps =
let (*) (matrix : IMatrix) (vector : IVector) =
(...)
This lets me write things like e.g. A * v where A is an IMatrix and v is an IVector. However, I now add the following line below the let-binding above:
let z = 1.0 * 2.0
and then, the F# compiler identifies this as an error. Hovering over "1.0", I get: "The type 'float' is not compatible with the type 'IMatrix", and similarly, hovering over "2.0", I get: "The type 'float' is not compatible with the type 'IVector'". What's going on here seems to be that the F# compiler fails to apply the multiplication operator for floats and instead applies the operator for IMatrix and IVector. If I instead write
let z = (1.0 : float) * (2.0 : float)
the problem persists, so adding explicit type annotions doesn't help. How can I ensure that F# picks the floating multiplication operator instead of the IMatrix / IVector operator I defined above?
F# doesn't allow you to define overloads just by adding let bound functions.
F# support standard .NET instance or static member overloads, so in this case you need to add a static member:
type Matrix =
static member (*) (matrix : Matrix) (vector : IVector) = ..
NOTE: I advise you against such design with overloads between matrices and vectors. If you continue defining overloads this way, I mean between mixed types, overload resolution may become ambiguous.
It's better to define the overload only between Matrices and then another set between Vectors. Then you can define a function like asMatrix
that allows you to wrap a vector in a Matrix and then multiply matrices.
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