为什么Scala在这个特定情况下找不到二级隐含值?

时间:2012-02-04 04:07:23

标签: scala polymorphism implicit

我很难解释两者之间的行为差​​异 由主要隐含值或者主要隐含值寻求的其他隐含值 隐式转换。具体来说,这有效:

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

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

> implicitly[Int]
5

但这不是:

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]

变:

  • 搜索是由implicitly启动还是隐式转换
  • 所追求的次要隐含值是否是多态的
  • 提供的辅助隐式值是否为多态

我得到以下结果:

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

如您所见,唯一不起作用的情况是搜索开始时 通过隐式转换,所寻求的值是多态的,但价值 提供的是单形的。

理论上有理由说明为什么会这样,或者这是一个 Scala的错误/限制?

2 个答案:

答案 0 :(得分:7)

你被scalac bug SI-3346咬了。更一般地,请参阅SI-4699的描述,尤其是第(1)点,

  

1)隐式搜索和隐式转换搜索以不同方式处理未确定类型参数

您正在直接观察案例区分隐含值和隐式转换的位置。

我已经更新了SI-3346,将其作为一个额外的例子。

答案 1 :(得分:3)

通过以下方式更改隐式转换的签名:

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

然后对定义了隐含值的类型值调用 aMethod ,即使用 String

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