2

下面給出的重複定義錯誤:多分派行爲重載

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

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

有沒有辦法來定義一個運算符重載使得F#承認我試圖基於函數簽名來調用函數?

例如朱莉婭有這個非常有用的功能:

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

F#進行了廣泛的類型推斷,並且對函數/運算符重載不太好。您需要內聯或將其放入課堂。 – s952163

+0

事實上,您似乎無法在擴展成員中重載運算符... – s952163

+1

[泛型參數類型的函數]的可能重複(http://stackoverflow.com/questions/501069/functions-with-generic-parameter-types) – Jwosty

回答

3

在這種特殊情況下,*已經過載。例如:

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#的行爲有些模糊,所以我重新做了Matrix和Vector類型的例子。你可以使其通用。也許有人更熟悉mathdotnet可以提供一個更習慣的解決方案。您還應該檢查是否*.*等。已經超載並且按預期運行,因爲對於常見操作,大部分這些東西都是already implemented