F# 运算符重载的多分派行为
以下给出了重复的定义错误:F# 运算符重载的多分派行为,f#,operator-overloading,math.net,F#,Operator Overloading,Math.net,以下给出了重复的定义错误: let (.*) (m1 : Matrix<float>) (m2 : Matrix<float>) = m1.Multiply(m2) let (.*) (v1 : Vector<float>) (v2 : Vector<float>) = v1.DotProduct(v2) let(.*)(m1:矩阵)(m2:矩阵)= m1.乘(m2) let(.*)(v1:向量)(v2:向量)= v1.DotP
let (.*) (m1 : Matrix<float>) (m2 : Matrix<float>) =
m1.Multiply(m2)
let (.*) (v1 : Vector<float>) (v2 : Vector<float>) =
v1.DotProduct(v2)
let(.*)(m1:矩阵)(m2:矩阵)=
m1.乘(m2)
let(.*)(v1:向量)(v2:向量)=
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
...
julia>方法(*)
#138泛型函数“*”的方法:
*(x::Bool,y::Bool)在Bool.jl:38
*{T在此特定情况下,*
已重载。例如:
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
您将得到与上面相同的结果。您可以使用*
,我只是避免使用它,以免与已定义的*
混淆。现在这实际上在和中进行了讨论,但F的行为有点模糊,因此我使用矩阵和向量类型重新编写了示例。您可能可以将其设置为泛型。也许有人更熟悉iar和mathdotnet可以提供一个更为惯用的解决方案。您还应该检查*
,*
等是否已经重载,并且函数是否符合您的预期,因为对于常见操作,这些内容中的大多数都是。F#进行了广泛的类型推断,并且不能很好地处理函数/运算符重载。您需要事实上,你似乎无法在扩展成员中重载运算符…顺便说一句,我看了Julia,这很好,但显然这是它的优点之一:“Julia程序围绕多个分派进行组织;通过定义函数并为不同的参数类型组合重载它们,而ch也可以是用户定义的。”
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