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也为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; }
欢迎任何建议!
解决方法
你可以像这样使用
here所描述的技巧:
open Symbolism type MathObjectOverloads = | MathObjectOverloads static member (?<-) (MathObjectOverloads,a: #MathObject,b: int) = MathObject.op_ExclusiveOr(a,b) static member (?<-) (MathObjectOverloads,b: #MathObject) = MathObject.op_ExclusiveOr(a,a: System.Int32,b) let inline ( ** ) a b = (?<-) MathObjectOverloads a b let two = Integer(2) let three = Integer(3) two ** three two ** 3 2 ** three
与链接的答案不同,我们必须使用(?< ;-)运算符,因为它是唯一可以取3个参数而不是2的运算符,我们需要在^运算符的左侧和右侧重载