我已经导入了一个向量数学库,并希望添加我自己的 (*) 和 (+) 运算符,同时保留基本 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)
这有两个问题:
int + int
和 int * int
, 和 如何在导入的 Vector 类型上定义一些可交换运算符,同时又不丢失对整数和浮点数的这些操作?
(我希望能够使用 * 和 + 在别处编写通用代码,而不必指定 float/Vector/int 类型约束)。
最佳答案
如果您能够修改库的源代码,则通过类型扩展添加一些重载会更简单:
type Vector with
static member (*) (x : Vector) (y : float) = x.Multiply(y)
static member (+) (x : Vector) (y : Vector) = x.Add(y)
但是,如果第一个操作数具有原始类型(例如您的第一个示例),则重载解析不再起作用。
无论如何,您可以利用成员重载并将约束传播到内联函数:
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
这适用于
(*)
的现有类型因为我们将它们保存在最后一个静态成员中。您可以对 (+)
执行相同操作运算符(operator)。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
即使您无法修改
Vector
,此技术也能奏效。类型。
关于f# - 如何在不破坏对其他类型的支持的情况下正确重载全局 (+) 和 (*),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15858474/