6

Symbolism библиотека перегружает арифметические операторы. Несмотря на то, что написано в C# я могу использовать его с F #:C# библиотека перегружает^оператор. Как использовать ** вместо этого?

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

Любые предложения приветствуются!

+0

Можете ли вы не объявлять одни и те же функции с другими типами операндов? –

+0

Hi @JonSkeet. Я не думаю, что F # -операторы (функции) перегружают метод C#. Это ты имел в виду? – dharmatech

ответ

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 

В отличие от связанного ответа, мы должны использовать - оператора, потому что это единственный оператор, который может принимать 3 аргумента вместо (<?) 2, и нам нужно перегрузить как левую, так и правую сторону оператора^

+0

Спасибо, Густаво! – dharmatech

+0

Я использую ваш '' 'трюк в течение некоторого времени, и мне любопытно, как вы узнали о'? <- ', и что это было необходимо/целесообразно здесь? Просто внимание к деталям в спецификации языка? – ildjarn

+0

Я узнал '' 'трюк из другого вопроса stackoverflow, который я связал, а затем мне нужен дополнительный параметр, и я вспомнил? <- взял 3 аргумента вместо 2. Я пошел в документы MSDN, чтобы узнать, есть ли еще один, но кажется, что нет –

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) 

 Смежные вопросы

  • Нет связанных вопросов^_^