6

Symbolism quá tải các toán tử số học của thư viện. Mặc dù nó được viết bằng C# Tôi có thể sử dụng nó từ F #:C# thư viện quá tải^toán tử. Cách sử dụng ** thay thế?

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) 

đầu ra:

3 + 6 * x + 13 * y + z 

Tuy nhiên, nó cũng quá tải ^ cho quyền hạn. Điều này tất nhiên không chơi tốt với F #.

Là một bước tiến trong việc khắc phục, tôi đã xuất khẩu một nhóm phương pháp, quyền hạn:

printfn "%A" (Aux.Pow(x, 2) * x) 

đầu ra:

x^3 

Làm thế nào tôi có thể quá tải ** sử dụng nhóm Aux.Pow phương pháp để thay thế?

tôi có thể làm một cái gì đó như thế này:

let (**) (a: MathObject) (b: MathObject) = Aux.Pow(a, b) 

Và đó không làm việc cho MathObject giá trị:

> x ** y * x;; 
val it : MathObject = x^(1 + y) 

Nhưng Aux.Pow bị quá tải cho int cũng như:

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

Bất kỳ đề nghị chào đón!

+0

Bạn không thể khai báo cùng chức năng với các loại toán hạng khác? –

+0

Xin chào @JonSkeet. Tôi không nghĩ rằng F # nhà khai thác (chức năng) quá tải cách C# phương pháp làm. Đó có phải ý của bạn? – dharmatech

Trả lời

10

Bạn có thể sử dụng các thủ thuật được mô tả here như thế này:

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 

Không giống như trong câu trả lời liên quan, chúng ta phải sử dụng - điều hành bởi vì đó là điều hành duy nhất có thể mất 3 đối số thay vì (<?) 2 và chúng tôi cần phải quá tải ở cả bên trái và bên phải của toán tử^

+0

Cảm ơn Gustavo! – dharmatech

+0

Tôi đã sử dụng thủ thuật '$' của bạn một thời gian, và tôi tò mò - làm thế nào bạn biết '? <-', và nó là cần thiết/thích hợp ở đây? Chỉ chú ý đến chi tiết trong thông số ngôn ngữ? – ildjarn

+0

Tôi đã học được mẹo '$' từ câu hỏi stackoverflow khác mà tôi đã liên kết, và sau đó tôi cần một tham số phụ và tôi nhớ? <- lấy 3 đối số thay vì 2. Tôi đã đi đến tài liệu MSDN để xem liệu có khác không, nhưng có vẻ như không có –

5

Đây là câu trả lời tương tự nhưng không có toán tử. Nó chỉ hoạt động trong F # 3.0 và bạn có thể sử dụng bất kỳ số tham số nào.

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) 
Các vấn đề liên quan