【问题标题】:C# library overloads ^ operator. How to use ** instead?C# 库重载 ^ 运算符。如何改用**?
【发布时间】:2013-03-14 05:17:38
【问题描述】:

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

欢迎提出任何建议!

【问题讨论】:

  • 不能用其他操作数类型声明相同的函数吗?
  • 嗨@JonSkeet。我认为 F# 运算符(函数)不会像 C# 方法那样重载。你是这个意思吗?

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


【解决方案1】:

您可以像这样使用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;- 的,而且这里有必要/合适?只注意语言规范中的细节?
  • 我从我链接的另一个 stackoverflow 问题中学到了$trick,然后我需要一个额外的参数,我记得 ?
  • @ildjarn, Gustavo Guerra:对于更多可以使用三元运算符的情况,请查看stackoverflow.com/questions/8309620/… 这个问题。在 F# 3.0 中,您可以使用静态成员而不是 stackoverflow.com/questions/4034802/… ,然后您可以拥有任意数量的参数,Github 中的 FsControl 项目使用这种技术来模拟类型类。
  • @Gustavo,我尝试使用静态成员而不是 ?
  • 好的,这里有一个静态成员的例子。
【解决方案2】:

这是相同的答案,但没有运算符。 它仅适用于 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-27
    • 2016-02-19
    • 1970-01-01
    • 2016-04-08
    相关资源
    最近更新 更多