Библиотека C# перегружает оператор ^. Как использовать ** вместо этого?
Библиотека 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; }
Любые предложения приветствуются!
2 ответа
Вы можете использовать описанный здесь трюк следующим образом:
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
В отличие от связанного ответа, мы должны использовать оператор (?<-), потому что это единственный оператор, который может принимать 3 аргумента вместо 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)