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

Ale*_*kol 4 f# static-methods type-inference operator-overloading

我在F#中编写了一个很小的矩阵库(主要是包装器方法),并且有一个关于静态运算符方法重载的问题,F#选择了一个我不打算过载的重载.

我有一个模块,我已经定义了矩阵与向量的右乘法:

[<AutoOpen>]
module MatrixOps =

let (*) (matrix : IMatrix) (vector : IVector) =
    (...)
Run Code Online (Sandbox Code Playgroud)

这让我可以编写像A*v这样的东西,其中A是IMatrix而v是IVector.但是,我现在在上面的let-binding下面添加以下行:

let z = 1.0 * 2.0
Run Code Online (Sandbox Code Playgroud)

然后,F#编译器将此识别为错误.将鼠标悬停在"1.0"上,我得到:"类型'浮点'与'IMatrix'类型不兼容,同样,悬停在"2.0"上,我得到:"类型'浮点'与类型不兼容' IVector'".这里发生的事情似乎是F#编译器无法对浮点数应用乘法运算符,而是将运算符应用于IMatrix和IVector.如果我反而写

let z = (1.0 : float) * (2.0 : float)
Run Code Online (Sandbox Code Playgroud)

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

Gus*_*Gus 8

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

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

type Matrix =
  static member (*) (matrix : Matrix) (vector : IVector) = ..
Run Code Online (Sandbox Code Playgroud)

注意:我建议您不要使用矩阵和向量之间的重载进行此类设计.如果以这种方式继续定义重载,我的意思是在混合类型之间,重载决策可能会变得模糊不清.

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