C#库重载^运算符。如何使用**代替?

时间:2013-03-11 16:08:34

标签: f# symbolic-math computer-algebra-systems symbolic-computation

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#。

作为解决方法的一步,我导出了一个功能方法组:

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的{​​{1}}也被重载了:

int

欢迎任何建议!

2 个答案:

答案 0 :(得分:10)

您可以使用here这样的技巧:

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

与链接的答案不同,我们必须使用(?&lt ;-)运算符,因为它是唯一可以使用3个参数而不是2的运算符,并且我们需要在^的左侧和右侧重载。操作

答案 1 :(得分: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)