2009-05-29 4 views
6

Tôi đã tạo ra một bất biến Queue trong F # như sau:Tôi nên sửa đổi lớp Queue của mình như thế nào để cho phép người dùng tạo hàng đợi rỗng của loại không xác định trong F #?

type Queue<'a>(f : 'a list, r : 'a list) =  
    let check = function 
     | [], r -> Queue(List.rev r, []) 
     | f, r -> Queue(f, r) 

    member this.hd = 
     match f with 
     | [] -> failwith "empty" 
     | hd :: tl -> hd 

    member this.tl = 
     match f, r with 
     | [], _ -> failwith "empty" 
     | hd::f, r -> check(f, r) 

    member this.add(x) = check(f, x::r) 

    static member empty : Queue<'a> = Queue([], []) 

Tôi muốn tạo ra một thể hiện của một sản phẩm nào Queue, tuy nhiên tôi nhận được một ngoại lệ giá trị gia hạn chế:

> let test = Queue.empty;; 

    let test = Queue.empty;; 
    ----^^^^ 

C : \ Documents and Settings \ juliet \ Local Settings \ Temp \ stdin (5,5): lỗi FS0030: Hạn chế giá trị. Giá trị 'thử nghiệm' đã được suy ra để có loại kiểm tra chung loại : Hàng đợi < '_a> Hoặc xác định' thử nghiệm 'làm thuật ngữ dữ liệu đơn giản, làm cho nó trở thành hàm có các đối số rõ ràng hoặc, nếu bạn không có ý định là chung chung, thêm chú thích kiểu.

Về cơ bản, tôi muốn cùng một loại chức năng nhìn thấy trong các mô-đun Set cho phép tôi viết:

> let test = Set.empty;; 

val test : Set<'a> 

Làm thế nào tôi có thể sửa đổi lớp Queue của tôi để cho phép người dùng tạo hàng đợi rỗng?

+2

* pojh * Đây phải là CW) –

+2

Kẻ bỏ phiếu: vui lòng cung cấp lý do tại sao bạn đã downvoted câu hỏi này. – Juliet

+0

@ Princess: Downvoting là ẩn danh. Tại sao bạn cần phải biết ai đã làm nó? – GEOCHET

Trả lời

6

Bạn cần phải sử dụng GeneralizableValueAttribute, a la:

type Queue<'a>(f : 'a list, r : 'a list) = // ' 
    let check = function 
     | [], r -> Queue(List.rev r, []) 
     | f, r -> Queue(f, r) 

    member this.hd = 
     match f with 
     | [] -> failwith "empty" 
     | hd :: tl -> hd 

    member this.tl = 
     match f, r with 
     | [], _ -> failwith "empty" 
     | hd::f, r -> check(f, r) 

    member this.add(x) = check(f, x::r) 
module Queue =  
    [<GeneralizableValue>] 
    let empty<'T> : Queue<'T> = Queue<'T>([], []) // ' 

let test = Queue.empty 
let x = test.add(1)  // x is Queue<int> 
let y = test.add("two") // y is Queue<string> 

Bạn có thể đọc thêm một chút về nó trong language spec.

+0

Tôi có thể thề rằng tôi đã viết chính xác điều đó, nhưng có vẻ như bạn đã viết nó tốt hơn. Nhiều đánh giá cao :) – Juliet