我使用日階2.10.0快照(20120522),並具有以下的Scala文件:scala 2.10.x.中的隱式解析這是怎麼回事?
這一個限定的類型類和基本類型類實例:
package com.netgents.typeclass.hole
case class Rabbit
trait Hole[A] {
def findHole(x: A): String
}
object Hole {
def apply[A: Hole] = implicitly[Hole[A]]
implicit val rabbitHoleInHole = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in Hole companion object"
}
}
這是包對象:
package com.netgents.typeclass
package object hole {
def findHole[A: Hole](x: A) = Hole[A].findHole(x)
implicit val rabbitHoleInHolePackage = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in Hole package object"
}
}
這裏是測試:
package com.netgents.typeclass.hole
object Test extends App {
implicit val rabbitHoleInOuterTest = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in outer Test object"
}
{
implicit val rabbitHoleInInnerTest = new Hole[Rabbit] {
def findHole(x: Rabbit) = "Rabbit found the hole in inner Test object"
}
println(findHole(Rabbit()))
}
}
正如你所看到的,Hole
是一個簡單的類型類,它定義了一個Rabbit
試圖找到的方法。我正試圖弄清楚它的隱式解決規則。
與未加註釋的所有四個類型類的實例,scalac抱怨上
rabbitHoleInHolePackage
和rabbitHoleInHole
歧義。 (爲什麼?)如果我註釋掉
rabbitHoleInHole
,scalac編譯和我回來「兔子發現孔封裝對象中的洞」。 (不應在局部範圍implicits優先?),如果我再註釋掉
rabbitHoleInHolePackage
,scalac抱怨上rabbitHoleInOuterTest
和rabbitHoleInInnerTest
歧義。 (爲什麼?在文章eed3si9n,下面列出的URL,他發現implicits BTW內部和外部的範圍可以採取不同的優先級。),如果我再註釋掉
rabbitHoleInInnerTest
,scalac編譯和我回來「兔子發現洞中在外部測試對象「中。
正如你所看到的,上述行爲並不遵循我在隱式解決方案上閱讀過的規則。我只描述了一小部分組合可以用來評論/取消註釋實例,其中大部分實際上都很奇怪 - 而且我還沒有涉及到進口和子類。
我已閱讀並觀看了presentation by suereth,stackoverflow answer by sobral和a very elaborate revisit by eed3si9n,但我仍然完全困惑不解。
你用2.9.x試過嗎? –
的行爲是不是在2.9.2 *與所有四個類型類實例註釋掉,scalac編譯不同,我回來「兔發現,在內部測試對象中的洞」 *如果我註釋掉rabbitHoleInHole,scalac編譯和我得到「兔子在內部測試對象中找到了洞」。 *如果我然後註釋掉rabbitHoleInHolePackage,scalac編譯,我回來了「兔子發現內部測試對象的洞」。 *如果我然後註釋掉rabbitHoleInInnerTest,scalac編譯並且我回來了「兔子在外部測試對象中找到了洞」。 –
斯卡拉的推理規則中有一個錯誤,達到了2.9,實際上Stack Overflow中的某個人發現了這個錯誤,他試圖理解規範是如何規定他所看到的行爲的。 –