我正在使用日期为(20120522)的 scala 2.10.0-snapshot 并具有以下 Scala 文件:
这个定义了 typeclass 和一个基本的 typeclass 实例:
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
是一个简单的类型类,它定义了一个 aRabbit
试图找到的方法。我试图弄清楚它的隐含解析规则。
由于所有四个类型类实例都未注释,scalac 抱怨
rabbitHoleInHolePackage
和rabbitHoleInHole
. (为什么?)如果我注释掉
rabbitHoleInHole
,scalac 编译并返回“Rabbit 在 Hole 包对象中找到了洞”。(本地范围内的隐含不应该优先吗?)如果我随后发表评论
rabbitHoleInHolePackage
,scalac 会抱怨 and 上的rabbitHoleInOuterTest
歧义rabbitHoleInInnerTest
。(为什么?在 eed3si9n 的文章,下面列出的 url 中,他发现隐式 btw 内部和外部范围可以采取不同的优先级。)如果我随后注释掉
rabbitHoleInInnerTest
,scalac 编译并返回“兔子在外部测试对象中找到了洞”。
如您所见,上述行为根本不遵循我所读过的关于隐式解析的规则。我只描述了在注释/取消注释实例时可以做的一小部分组合,其中大多数确实很奇怪——而且我还没有进入导入和子类。
我已经阅读并观看了 suereth 的演示文稿、sobral的stackoverflow 回答以及 eed3si9n的非常详尽的重访,但我仍然完全感到困惑。