如何使用重载的静态运算符

How to use overloaded static operators

我正在用 F# 编写一个小型矩阵库(主要是包装器方法),并且在静态运算符方法的重载方面遇到问题,F# 选择了我不希望的重载。

我有一个模块,我在其中定义了矩阵与向量的右乘:

[<AutoOpen>]
module MatrixOps =

let (*) (matrix : IMatrix) (vector : IVector) =
    (...)

这让我可以写一些东西,例如A * v 其中 A 是 IMatrix,v 是 IVector。但是,我现在在上面的 let-binding 下面添加以下行:

let z = 1.0 * 2.0

然后,F# 编译器将此识别为错误。将鼠标悬停在“1.0”上,我得到:"The type 'float' is not compatible with the type 'IMatrix",同样,将鼠标悬停在“2.0”上,我得到:"The type 'float' is not compatible with the type 'IVector'"。这里发生的事情似乎是 F# 编译器未能将乘法运算符应用于浮点数,而是将运算符应用于 IMatrix 和 IVector。如果我改写

let z = (1.0 : float) * (2.0 : float)

问题仍然存在,因此添加显式类型注释没有帮助。如何确保 F# 选择浮点乘法运算符而不是我在上面定义的 IMatrix / IVector 运算符?

F# 不允许您仅通过添加 let 绑定函数来定义重载。

F# 支持标准.NET 实例或静态成员重载,因此在这种情况下您需要添加一个静态成员:

type Matrix =
  static member (*) (matrix : Matrix) (vector : IVector) = ..

注意:我建议您不要在矩阵和向量之间进行这种重载的设计。如果您继续以这种方式定义重载,我的意思是在混合类型之间,重载解析可能会变得不明确。

最好只在矩阵之间定义重载,然后在向量之间定义另一组重载。然后你可以定义一个像asMatrix这样的函数,它允许你将一个向量包装在一个矩阵中,然后乘以矩阵。