Duc*_*tro 3 f# operator-overloading
我已经导入了一个矢量数学库,并希望添加我自己的(*)和(+)运算符,同时保留基本int和float的现有运算符.
我尝试过以下方法:
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)
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
int + int和int * int,和如何在我导入的Vector类型上定义一些可交换运算符,同时也不会在int和float上丢失这些操作?
(我希望能够使用*和+在其他地方编写通用代码,而不必指定float/Vector/int类型约束).
pad*_*pad 10
如果您能够修改库的源代码,则通过类型扩展添加一些重载更简单:
type Vector with
static member (*) (x : Vector) (y : float) = x.Multiply(y)
static member (+) (x : Vector) (y : Vector) = x.Add(y)
Run Code Online (Sandbox Code Playgroud)
但是,如果第一个操作数具有基本类型(例如,您的第一个示例),则重载分辨率不再起作用.
无论如何,您可以利用成员重载并将约束传播到内联函数:
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 (*) x y = (?<-) VectorOverloadsMult x y
Run Code Online (Sandbox Code Playgroud)
这适用于现有类型,(*)因为我们将它们保存在最后一个静态成员中.你可以为(+)运营商做同样的事情.
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
Run Code Online (Sandbox Code Playgroud)
即使您无法修改Vector类型,此技术也可以使用.