2011-07-27 58 views
6

Tại sao không thực hiện công việc sau?Hiểu "đối số kiểu không tuân theo giới hạn tham số kiểu" lỗi trong Scala

scala> abstract class Foo[B<:Foo[B]] 
defined class Foo 

scala> class Goo[B<:Foo[B]](x: B) 
defined class Goo 

scala> trait Hoo[B<:Foo[B]] { self: B => new Goo(self) } 
<console>:9: error: inferred type arguments [Hoo[B] with B] do not conform to class Goo's type parameter bounds [B <: Foo[B]] 
     trait Hoo[B<:Foo[B]] { self: B => new Goo(self) } 
             ^

scala> trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) } 
<console>:9: error: inferred type arguments [Hoo[B]] do not conform to class Goo's type parameter bounds [B <: Foo[B]] 
     trait Hoo[B<:Foo[B]] extends Foo[B] { new Goo(this) } 
              ^

Trong lần thử đầu tiên, không phải là Hoo[B] with B <: Foo[B]?

Trong lần thử thứ hai, không phải là Hoo[B] <: Foo[B]?

Để thúc đẩy vấn đề này, có một thư viện với:

// "Foo" 
abstract class Record[PK, R <: Record[PK, R]] extends Equals { this: R => 
    implicit def view(x: String) = new DefinitionHelper(x, this) 
    ... 
} 
// "Hoo" 
class DefinitionHelper[R <: Record[_, R]](name: String, record: R) { 
    def TEXT = ... 
    ... 
} 

// now you can write: 
class MyRecord extends Record[Int, MyRecord] { 
    val myfield = "myfield".TEXT 
} 

Tôi đang cố gắng để giới thiệu một phương pháp mở rộng mới bên cạnh TEXT gọi BYTEA, vì vậy mà người ta có thể viết:

class MyRecord extends XRecord[Int, MyRecord] { 
    val myfield = "myfield".BYTEA // implicit active only inside this scope 
} 

My lần thử:

class XDefinitionHelper[R <: Record[_, R]](name: String, record: R) { 
    def BYTEA = ... 
} 

trait XRecord[PK, R <: Record[PK, R]] { self: R => 
    implicit def newView(x: String) = new XDefinitionHelper(x, self) 
} 

Nhưng điều này xảy ra cùng một vấn đề với trường hợp thử nghiệm nhỏ hơn ở trên.

Trả lời

2

Trong lần thử đầu tiên, bạn có Hoo[B] with B <: Foo[B]. Nhưng đối với Goo[Hoo[B] with B] để tồn tại, bạn cần Hoo[B] with B <: Foo[Hoo[B] with B]. Tương tự như vậy trong trường hợp thứ hai.

+0

Cảm ơn, bây giờ tôi thấy làm thế nào để sửa chữa thứ hai của tôi cố gắng (bằng cách sử dụng 'mở rộng Foo [Hoo [B]]'), nhưng làm thế nào một sửa chữa hình thức đầu tiên (sử dụng tự loại)? – Yang

+0

Cũng gặp sự cố khi thực hiện việc này thêm. Tôi cần định nghĩa một lớp 'Ioo [B <: Ioo [B]] mở rộng Hoo [B] {new Goo (this)}' nhưng nó không hoạt động. Cũng không mở rộng Hoo [Ioo [B]] '. Nhưng 'lớp Ioo [B <: Foo [B]] mở rộng tác phẩm Hoo [B]', gọi 'Goo' trên một thể hiện của' Ioo' từ bên trong 'Hoo'. Nhưng tôi không thể làm điều đó từ bên trong 'Ioo'. – Yang

+0

Điều trên thực sự là: Tôi cần phải định nghĩa một lớp 'Ioo mở rộng Hoo [Ioo] {new Goo (this)}' nhưng nó không hoạt động. Cũng không mở rộng Hoo [Foo [Ioo]] '. – Yang

0

Điều này có vẻ quá đơn giản đến mức khó tin (ví dụ .: là một thực hành tốt), nhưng điều này lưu ngày của tôi anyway, do đó nó ở đâu:

scala> trait MyTrait[T <: MyTrait[T]] { self: T => def hello = println("hello") } 

scala> case class User(t: MyTrait[_]) 
<console>:8: error: type arguments [_$1] do not conform to trait MyTrait's type parameter bounds [T <: MyTrait[T]] 
     case class User(t: MyTrait[_]) 

scala> case class User(t:() => MyTrait[_]) 
defined class User 
Các vấn đề liên quan