6

Symbolismライブラリは算術演算子をオーバーロードします。それはC#で書かれているが、私は、F#からそれを使用することができます。C#ライブラリは^演算子をオーバーロードします。代わりに**を使用する方法は?

open Symbolism 

let x = new Symbol("x") 
let y = new Symbol("y") 
let z = new Symbol("z") 

printfn "%A" (2*x + 3 + 4*x + 5*y + z + 8*y) 

出力:

3 + 6 * x + 13 * y + z 

しかし、それはまた、権力のため^をオーバーロード。これはもちろん、F#ではうまくいきません。

回避策に向けたステップとして、私は権力のための方法グループをエクスポート:

printfn "%A" (Aux.Pow(x, 2) * x) 

出力:

x^3 

私が代わりにAux.Powメソッドグループを使用する**をオーバーロードすることができますどのように?

私はこのような何か行うことができます。

let (**) (a: MathObject) (b: MathObject) = Aux.Pow(a, b) 

をそして、それはMathObject値のための作業を行います。

> x ** y * x;; 
val it : MathObject = x^(1 + y) 

しかしAux.Powが同様intオーバーロードされます。

public static MathObject Pow(MathObject a, MathObject b) 
    { return new Power(a, b).Simplify(); } 

    public static MathObject Pow(MathObject a, int b) 
    { return a^new Integer(b); } 

    public static MathObject Pow(int a, MathObject b) 
    { return new Integer(a)^b; } 

どれでも提案は歓迎! (?< - ):

+0

他のオペランドの型と同じ関数を宣言できませんか? –

+0

こんにちは@JonSkeet。私はF#演算子(関数)がC#の方法のやり方をオーバーロードするとは思わない。それはあなたが意味することですか? – dharmatech

答えて

10

あなたがトリックを使用することができますが、このようhereを説明し、それは代わりに3つの引数を取ることができる唯一の事業者だからオペレータリンクの答えとは異なり

open Symbolism 

type MathObjectOverloads = 
    | MathObjectOverloads 
    static member (?<-) (MathObjectOverloads, a: #MathObject, b: int) = MathObject.op_ExclusiveOr(a, b) 
    static member (?<-) (MathObjectOverloads, a: #MathObject, b: #MathObject) = MathObject.op_ExclusiveOr(a, b) 
    static member (?<-) (MathObjectOverloads, a: System.Int32, b: #MathObject) = MathObject.op_ExclusiveOr(a, b) 

let inline (**) a b = (?<-) MathObjectOverloads a b 

let two = Integer(2) 
let three = Integer(3) 

two ** three 

two ** 3 

2 ** three 

を、私たちが使用する必要があります2であり、^演算子の左右の両方にオーバーロードする必要があります。

+0

ありがとうGustavo! – dharmatech

+0

私は今あなたの '$ 'トリックをしばらく使っていますが、私は好奇心が強いです。あなたは'?< - 'についてどうやって知っていましたか?言語仕様の詳細に注意してください。 – ildjarn

+0

私はリンクされた他のstackoverflowの質問から '$ 'トリックを学びました、そして、余分なパラメータが必要でした。私は思い出しましたか?< - は2つではなく3つの引数をとりました。MSDNのドキュメントに、しかしそれはないと思われる –

5

演算子のない同じ答えは同じです。 F#3.0でのみ動作し、任意の数のパラメータを使用できます。

let inline i3 (a:^a,b:^b,c:^c) = ((^a or ^b or ^c) : (static member threeParams: ^a* ^b* ^c -> _) (a,b,c)) 

open Symbolism 

type MathObjectOverloads = 
    | MathObjectOverloads 
    static member threeParams (MathObjectOverloads, a: #MathObject , b: int  ) = MathObject.op_ExclusiveOr(a, b) 
    static member threeParams (MathObjectOverloads, a: #MathObject , b: #MathObject) = MathObject.op_ExclusiveOr(a, b) 
    static member threeParams (MathObjectOverloads, a: System.Int32, b: #MathObject) = MathObject.op_ExclusiveOr(a, b) 

let inline (**) a b = i3(MathObjectOverloads, a, b) 
関連する問題