2012-01-12 22 views
5

Tôi muốn xác định một đặc điểm Swappable với hai giá trị x,y và một phương pháp swap như vậy gọi swap vào một đối tượng kế thừa từ Swappable lợi nhuận một đối tượng cùng loại với x,y chuyển. tốt nhất của tôi cho đến nay là:Trait thể thay thế nhanh trong Scala

trait Swappable[T] { 
    val x: T 
    val y: T 
    def swap: Swappable[T] = { 
    val (a,b) = (x,y) 
    new Swappable[T] { val x=b; val y=a } 
    } 
} 

Nhưng đây không phải là những gì tôi muốn vì kiểu trả về của swap là một số lớp ẩn danh, thay vì lớp ban đầu tôi bắt đầu với, vì vậy tôi nhận được lỗi như:

def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap 
<console>:32: error: type mismatch; 
found : Swappable[Int] 
required: S 
     def direct[S<:Swappable[Int]](s: S): S = if (s.x > s.y) s else s.swap 
                     ^

Tôi có thể làm những gì tôi đang cố gắng làm không? Chữ ký loại chính xác cho trao đổi là gì?

Trả lời

7

Tôi không biết làm thế nào để làm điều đó, nhưng tôi nghĩ có lẽ nó sẽ giúp để có được một ý tưởng tốt hơn về những gì chính xác bạn muốn xảy ra. Hãy xem xét một lớp học như

case class Foo(x: Int, y: Int) extends Swappable[Int] { 
    val z = x 
} 

Bây giờ, nếu bạn có f = Foo(1, 2), nên f.swap cung cấp cho bạn một Foo nơi x != z? Nếu vậy, không có cách nào trong Scala để tạo ra một Foo như thế. Nếu không, nó thực sự có nghĩa là gì để "trao đổi x và y"?

Có lẽ những gì bạn đang thực sự tìm kiếm là một cái gì đó như thế này:

trait Swappable[A,T] { 
    this: A => 

    val x: T 
    val y: T 
    def cons(x: T, y: T): A 

    def swap = cons(y, x) 
} 

case class Foo(x: Int, y: Int) extends Swappable[Foo,Int] { 
    val z = x 

    def cons(x: Int, y: Int) = copy(x=x, y=y) 
} 

Nhưng tôi không chắc chắn.

+0

Very nice! Bạn làm cho một điểm tốt là khái niệm về trao đổi không rõ ràng nói chung. Trong tình huống của tôi, tôi sẽ chỉ mở rộng 'Swappable' với các trường hợp 'Foo (x: T, y: T)' không chứa thêm giá trị nào, nhưng không có nhiều cách để Scala biết điều đó. Vì vậy, tôi đoán tôi sẽ để lại việc thực hiện phương thức 'swap' cho mỗi lớp kế thừa (mà về cơ bản là những gì bạn làm, thông qua phương thức bổ sung' cons'). Chìa khóa để thực hiện điều này (mà tôi đã không nghĩ đến) là truyền tham số kiểu bổ sung 'A' sang' Swappable', cho phép kế thừa các lớp kế thừa kiểu trả về. Cảm ơn! – davidsd

3

gì về điều gì đó như thế:

trait Swappable[T] { 
    type A 
    val x: T 
    val y: T 

    def create(a: T, b: T): A 
    def swap = create(y, x) 
} 

case MySwappable[T](x: T, y: T) extends Swappable[T] { 
    type A = MySwappable 
    def create(a: T, b: T) = MySwappable(a, b) 
} 
+0

Phải, điều này rất giống với giải pháp của Owen. – davidsd

+1

Chỉ để tham khảo, câu hỏi này được gọi là "MyType": http://www.scala-lang.org/node/6649 (và chưa có câu trả lời ít được soạn sẵn trong Scala) – Eric

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