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であるので、あなたのために、すでに過負荷で機能しています。