2012-06-27 26 views
5

Thông thường, khi thu thập tất cả các phần tử của chuỗi khớp với một loại cụ thể, bộ sưu tập kết quả có cả loại bộ sưu tập độc đáo và kiểu chọn để:Scala: Có tham số kiểu của bộ sưu tập tồn tại "thu thập" khi tham số kiểu là loại thành viên

trait Foo 
trait Bar 

trait Baz { 
    // Works 
    def def1(foo: Seq[Foo]): Seq[Foo with Bar] = 
    foo collect {case foobar: Bar => foobar} 
} 

thậm chí này hoạt động khi các loại đầu vào được tham số hóa bằng một loại thành viên bị chặn và tất cả tôi muốn trở lại là một chuỗi tham số bởi các loại ràng buộc (không phải là loại thành viên):

trait Baz { 
    type memberType <: Foo 

    // Works 
    def2(foo: Seq[memberType]): Seq[Foo with Bar] = 
    foo collect {case foobar: Bar => foobar} 
} 

Tuy nhiên, fai này ls khi tôi thực sự muốn trở lại một chuỗi tham số của các loại thành viên: nhắn

trait Baz { 
    type memberType <: Foo 

    // Fails 
    def def3(foo: Seq[memberType]): Seq[memberType with Bar] = 
    foo collect {case foobar: Bar => foobar} 
} 

Lỗi:

error: type mismatch; 
found : Seq[this.Foo with this.Bar] 
required: Seq[Baz.this.memberType with this.Bar] 
    foo collect {case foobar: Bar => foobar} 

Để phục hồi chức năng, tôi có thể bao gồm các loại thành viên trong collect cuộc gọi, nhưng điều đó dường như không cần thiết cho rằng mọi phần tử phải khớp với loại đó vì chữ ký:

trait Baz { 
    type memberType <: Foo 

    // Works 
    def def4(foo: Seq[memberType]): Seq[memberType with Bar] = 
    foo collect {case foobar: memberType with Bar => foobar} 
} 

Có cách nào để xác định chuỗi các loại thành viên để chúng nhớ loại thành viên của họ khi collect được chỉnh sửa?

+1

Bạn đã kiểm tra mã đó để cảnh báo? Vì 'memberType' là trừu tượng, nó bị xóa trong kiểm tra' foobar: memberType with Bar'. –

+0

Tôi hơi bối rối vì sao 1 và 2 thậm chí còn hoạt động. Chuỗi được thu thập chỉ là một Seq [Bar] nhưng trình biên dịch vẫn cho phép nó được gõ như là một Seq [Foo with Bar]. Được rồi, tôi đoán tôi bối rối hơn vì sao điều này không dẫn đến cảnh báo xóa. – Kaito

+0

Tôi không thấy cảnh báo khi chạy bất kỳ ví dụ nào. Loại tẩy xóa có ảnh hưởng gì đến ví dụ cuối cùng (đã được chỉnh sửa để cho biết chính xác rằng nó "Hoạt động") không? – drhagen

Trả lời

1

Đây không phải là câu trả lời mà chỉ là một số quan sát. Đây hoạt động:

trait Baz[A <: Foo] { 
    def def3(foo: Seq[A]): Seq[A] = 
    foo collect {case foobar => foobar} 
} 

nhưng điều này không:

trait Baz[A <: Foo] { 
    def def3(foo: Seq[A]): Seq[A] = 
    foo collect {case foobar: Bar => foobar} 
} 

cũng này không:

trait Baz[A] { 
    def def3(foo: Seq[A]): Seq[A] = 
    foo collect {case foobar: Bar => foobar} 
} 

nên nó có vẻ là một tác động của khớp mẫu; Tôi không nghĩ rằng nó có bất cứ điều gì để làm với collect nói riêng. Bằng cách nào đó, nó sẽ xóa thông tin ngay sau khi bạn thêm loại vào trường hợp phù hợp: -/

Nhưng như Kaito, tôi cũng thực sự ngạc nhiên khi hai trường hợp đầu tiên của bạn làm việc. Nó phải là (và có vẻ hợp lý) rằng thuật toán suy luận kiểu tạo ra sự khác biệt giữa một loại ổn định đã biết (Foo) và một kiểu tham số hoặc kiểu thành viên. Bạn có thể cần phải hỏi về danh sách gửi thư ngôn ngữ scala để có được một số chuyên gia biên dịch để trả lời câu hỏi ...

Các vấn đề liên quan