6

Symbolismライブラリは、算術演算子をオーバーロードします。C# で書かれていますが、F# から使用できます。

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# ではうまく機能しません。

回避策として、powers のメソッド グループをエクスポートしました。

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; }

どんな提案でも大歓迎です!

4

2 に答える 2

10

ここで説明されているトリックを次のように使用できます。

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 つではなく 3 つの引数を取ることができる唯一の演算子であり、^ 演算子の左側と右側の両方でオーバーロードする必要があるためです。

于 2013-03-11T16:30:53.277 に答える
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)
于 2013-03-13T18:50:04.843 に答える