2012-02-04 29 views
8

Tôi đang gặp khó khăn trong việc giải thích sự khác biệt về hành vi giữa các giá trị tiềm ẩn bổ sung bằng một giá trị tiềm ẩn chính hoặc một chuyển đổi ẩn ngụ ý . Cụ thể, công trình này:Tại sao Scala không tìm thấy giá trị ngầm thứ hai trong trường hợp cụ thể này?

trait Foo[A] 
implicit def fooString: Foo[String] = null 

implicit def value[A](implicit foo: Foo[A]) = 5 

> implicitly[Int] 
5 

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

implicit def conversion[A](x: Int)(implicit foo: Foo[A]) = new { 
    def aMethod = 5 
} 

> 1.aMethod 
could not find implicit value for parameter foo: test.Foo[A] 

khác nhau:

  • Cho dù việc tìm kiếm được bắt đầu bởi implicitly hay một chuyển đổi ngầm
  • Cho dù ngầm thứ giá trị sau khi tìm kiếm là đa hình
  • Dù giá trị tiềm ẩn thứ cấp là đa hình

tôi nhận được kết quả như sau:

Conversion/value Searching for Supplied | Works? 
---------------- ------------- -------- | ------ 
    conversion  poly   poly | yes 
    conversion  poly   mono | **no** 
    conversion  mono   poly | yes 
    conversion  mono   mono | yes 
    value   poly   poly | yes 
    value   poly   mono | yes 
    value   mono   poly | yes 
    value   mono   mono | yes 

Như bạn thấy, trường hợp duy nhất mà không hoạt động được khi tìm kiếm được bắt đầu bởi một chuyển đổi ngầm, giá trị được tìm kiếm là đa hình, nhưng giá trị được cung cấp là đơn hình.

Có lý do lý thuyết nào giải thích tại sao điều này xảy ra hay đây là lỗi /giới hạn của Scala?

Trả lời

7

Bạn đang bị cắn bởi lỗi scalac SI-3346. Nhìn chung, hãy xem mô tả của SI-4699, đặc biệt. điểm (1),

1) tìm kiếm tiềm ẩn và tìm kiếm chuyển đổi tiềm ẩn đối xử với các tham số kiểu không xác định khác nhau

mà bạn đang quan sát trực tiếp nơi trường hợp của bạn được phân biệt giữa các giá trị tiềm ẩn và chuyển đổi ngầm.

Tôi đã cập nhật SI-3346 để bao gồm điều này làm ví dụ bổ sung.

3

Thay đổi chữ ký của người chuyển đổi ngầm theo cách sau:

implicit def conversion[A](a: A)(implicit foo: Foo[A]) = new { 

Sau đó gọi aMethod về một giá trị kiểu mà một giá trị tiềm ẩn được xác định, tức là với một String :

scala> "foo".aMethod 
res0: Int = 5 
+1

Câu trả lời đúng, câu hỏi sai ;-) –

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