运算符重载的多个调度行为

时间:2016-07-25 03:22:45

标签: class f# operator-overloading overloading mathdotnet

以下内容给出了重复的定义错误:

let (.*) (m1 : Matrix<float>) (m2 : Matrix<float>) =
    m1.Multiply(m2)

let (.*) (v1 : Vector<float>) (v2 : Vector<float>) =
    v1.DotProduct(v2)

有没有办法定义一个运算符重载,以便F#根据函数签名识别我试图调用的函数?

例如Julia有这个非常有用的功能:

julia> methods(*)
# 138 methods for generic function "*":
*(x::Bool, y::Bool) at bool.jl:38
*{T<:Unsigned}(x::Bool, y::T<:Unsigned) at bool.jl:53
*(x::Bool, z::Complex{Bool}) at complex.jl:122
*(x::Bool, z::Complex{T<:Real}) at complex.jl:129
...

如果有一种方法可以在F#中复制类似的东西,那将会很棒。 感谢。

1 个答案:

答案 0 :(得分:2)

在这种特定情况下,*已经超载。例如:

let m = matrix [[ 1.0; 4.0; 7.0 ]
                [ 2.0; 5.0; 8.0 ]
                [ 3.0; 6.0; 9.0 ]]
let v = vector [ 10.0; 20.0; 30.0 ]
let s = 5.

m * m
//val it : Matrix<float> =
//  DenseMatrix 3x3-Double
//30  66  102
//36  81  126
//42  96  150

v * v
//val it : float = 1400.0

有超载

type Mult = Mult with
    static member inline ( $ ) (Mult, m1:Matrix<float>) = fun (m2:Matrix<float>) -> m1.Multiply(m2)
    static member inline ( $ ) (Mult, v1:Vector<float>) = fun (v2:Vector<float>) -> v1.DotProduct(v2)

let inline ( .*. ) v1 v2 = (Mult $ v1) v2

你可以像这样使用它:

m .*. m
v .*. v

您将获得与上述相同的结果。您可以使用.*,我只是避免使用它,以免与已定义的.*混淆。现在实际上在Global Operator OverloadingOveload operator in F#中讨论了这一点,但是F#在这里的行为有点模糊,所以我用矩阵和矢量类型重新做了这个例子。你可以把它变成通用的。也许更熟悉mathdotnet的人可以提供更加惯用的解决方案。您还应该检查*.*等。已经超载并且按预期运行,因为对于常见操作,大部分内容都是already implemented

相关问题