以下内容给出了重复的定义错误:
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#中复制类似的东西,那将会很棒。 感谢。
答案 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 Overloading和Oveload operator in F#中讨论了这一点,但是F#在这里的行为有点模糊,所以我用矩阵和矢量类型重新做了这个例子。你可以把它变成通用的。也许更熟悉mathdotnet的人可以提供更加惯用的解决方案。您还应该检查*
,.*
等。已经超载并且按预期运行,因为对于常见操作,大部分内容都是already implemented。