2016-11-29 13 views
4

F#で小さな行列ライブラリ(主にラッパーメソッド)を作成していますが、静的演算子メソッドのオーバーロードに関する問題があります。オーバーロードされた静的演算子の使用方法

[<AutoOpen>] 
module MatrixOps = 

let (*) (matrix : IMatrix) (vector : IVector) = 
    (...) 

これは私が、例えばのようなものを書くことができます:

私は、ベクトルと行列の右乗算を定義したモジュールを持っていますA * vここで、AはIMatrixであり、vはIVectorである。しかし、私は今、上記のレットバインディングの下に次の行を追加します:F#コンパイラはこれをエラーとして識別します。 "1.0"をホバリングすると、次のようになります。 "タイプ 'float'はタイプ 'IMatrix'と互換性がありません。同様に、2.0以上にホバリングすると、"タイプ 'float' IVector '"ここで起こっていることは、F#コンパイラがfloatに乗算演算子を適用せず、代わりにIMatrixとIVectorの演算子を適用しているようです。私が代わりに

let z = (1.0 : float) * (2.0 : float) 

を記述する場合の問題は解消されないので、明示的な型annotionsを追加することは助けにはなりません。上記で定義したIMatrix/IVector演算子の代わりに、F#が浮動乗算演算子を選択するようにするにはどうすればよいですか?

+2

オーバーロードをオブジェクトの1つのタイプの静的メンバーにしたい場合は、希望どおりに動作します。 –

+0

大丈夫です。しかし、別の方法がありますか?乗算方法がIMatrixまたはIVectorのいずれかのインターフェイスにある場合は、不要な依存関係を導入することになります。 –

+1

これは依存関係ではありません。とにかくタイプが必要です –

答えて

8

F#では、レットバインド関数を追加するだけでオーバーロードを定義することはできません。

type Matrix = 
    static member (*) (matrix : Matrix) (vector : IVector) = .. 

注:

のF#のサポート標準の.NETインスタンスまたは静的メンバオーバーロードが、この場合のように、あなたは静的メンバを追加する必要があり、私は行列やベクトル間の過負荷で、このような設計に対してあなたをお勧めします。このように過負荷を定義し続けると、混在したタイプ間で、過負荷の解決があいまいになることがあります。

行列間だけオーバーロードを定義し、ベクトル間に別のセットを定義する方がよいでしょう。次に、asMatrixのような関数を定義して、ベクトルを行列にラップして行列を乗算することができます。

+0

私はこれを誤植だと思う:_ MatricesとVectors_の間に過負荷を定義する方が良い。 –

+0

@FyodorSoikinのような、あなたは私がそれがはっきりしていないことに気づいたと言いました。私はそれを言い換えるでしょう。ありがとう! – Gustavo

+0

ありがとうございます。私はasMatrixに関するあなたのコメントは健全だと思います。私はいくつかのフォローアップの質問があります。私が(文字通り)上記を行うと、MatrixはIVectorに依存します。私はむしろ2つを結合したくない。結合を避ける潜在的な方法は、「IMatrixインターフェースで静的拡張メソッド」を定義することですが、インターフェースに静的メソッドを持たせることはできません。この作業を行う唯一の方法は、依存関係を導入することでしょうか? –

関連する問題