Say chúng tôi có hai đặc điểm sau đây:Scala xem ứng dụng puzzler
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar
Và một chuyển đổi ngầm từ thứ hai đến thứ nhất:
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
Chúng tôi tạo ra một Bar
và một danh sách các số nguyên:
val bar = new Bar {}
val stuff = List(1, 2, 3)
Bây giờ tôi hy vọng những điều sau đây sẽ hoạt động:
bar howMany stuff
Nhưng nó không:
scala> bar howMany stuff
<console>:13: error: type mismatch;
found : List[Int]
required: List[A]
bar howMany stuff
^
Vì vậy, chúng tôi đi đến the spec, trong đó có điều này để nói (nhấn mạnh in đậm là của tôi):
Lần được áp dụng trong ba tình huống .
[Không phải là liên quan ở đây.]
Trong một lựa chọn em với e loại T, nếu chọn m không biểu thị một thành viên của T. Trong trường hợp này, chế độ xem v được tìm kiếm trong đó được áp dụng cho e và kết quả có chứa thành viên có tên m. Số tiền tìm kiếm được tiến hành như trong trường hợp các tham số ngầm định, trong đó phạm vi tiềm ẩn là một trong số T. Nếu tìm thấy một chế độ xem như vậy, lựa chọn e.m được chuyển đổi thành v (e) .m.
Trong một lựa chọn em (args) với e loại T, nếu chọn m biểu thị một số thành viên (s) của T, nhưng không ai trong số những thành viên được áp dụng cho đối số args. Trong trường hợp này một cái nhìn v được tìm kiếm đó là áp dụng đối với e và có kết quả chứa một phương thức m đó là áp dụng đối với args. Tìm kiếm tiếp tục như trong trường hợp của thông số tiềm ẩn, trong đó phạm vi tiềm ẩn là một trong số T. Nếu một chế độ xem như vậy được tìm thấy, lựa chọn e.m được chuyển đổi thành v (e) .m (args).
Vì vậy, chúng tôi cố gắng sau, suy nghĩ nó phải là quá vô lý làm việc:
trait Foo[A] { def howMany(xs: List[A]) = xs.size }
trait Bar { def howMany = throw new Exception("I don't do anything!") }
implicit def bar2foo[A](bar: Bar) = new Foo[A] {}
val bar = new Bar {}
val stuff = List(1, 2, 3)
Nhưng nó (trên cả hai 2.9.2 và 2.10.0-RC2, ít nhất) :
scala> bar howMany stuff
res0: Int = 3
Điều này dẫn đến một số hành vi thực sự kỳ lạ, như ví dụ trong this workaround cho this problem.
Tôi có ba câu hỏi (liên quan chặt chẽ):
- Có cách nào đơn giản (ví dụ, một trong những điều đó không liên quan đến việc thêm các phương pháp giả mạo với tên thích hợp) có quan điểm áp dụng một cách chính xác trong bản gốc trường hợp trên?
- Ai đó có thể cung cấp thông tin chi tiết về hành vi này không?
- Giả sử đây là hành vi dự định, nó có ý nghĩa gì không?
Tôi cũng đánh giá cao bất kỳ liên kết nào đến các cuộc thảo luận trước đây về vấn đề này — Tôi đã không có nhiều may mắn với Google.
Điều đó làm việc trong trường hợp được đơn giản hóa cụ thể đó, nhưng nói chung tôi quan tâm đến 'A' — trong giải pháp cho vấn đề Scalaz được liên kết trong câu hỏi, ví dụ. –