在嵌套类型

时间:2015-11-24 16:38:15

标签: scala typeclass implicit

我有一个特征Outer,其成员F是一个类型构造函数。我想为F提供类型类实例,但不知何故,scalac的隐式解析在某个时刻停止工作。

我尝试构建一个较小的最小示例,但我必须在下面添加所有内容才能显示错误。注意倒数第二行仍然是如何编译的,从sub中的嵌套伴随对象中正确地拾取隐含。

但最后一行不再编译了。另请注意,在倒数第二行中指定隐式方法时,它会进行编译。

任何人都可以提供为什么会发生这种情况的线索吗?

trait TC[F[_]]

trait Outer[N[_]] {
  trait F[_]
  object F {
    implicit val tcInst: TC[F] = new TC[F]{}
  }
}

case class Sub[N[_]]() extends Outer[N]

object Test{
  implicit val optionInst: TC[Option] = new TC[Option]{}

  val sub = Sub[Option]()
  val sub2 = Sub[sub.F]()

  implicitly[TC[sub.F]]                  //compiles
  implicitly[TC[sub2.F]](sub2.F.tcInst)  //compiles
  implicitly[TC[sub2.F]]                 //doesn't compile
}

最后一行产生以下错误:

Error:(22, 13) could not find implicit value for parameter e: test.novariance.TC[test.novariance.Test.sub2.F]
  implicitly[TC[sub2.F]]                 //doesn't compile
            ^
Error:(22, 13) not enough arguments for method implicitly: (implicit e: test.novariance.TC[test.novariance.Test.sub2.F])test.novariance.TC[test.novariance.Test.sub2.F].
Unspecified value parameter e.
  implicitly[TC[sub2.F]]                 //doesn't compile
            ^

1 个答案:

答案 0 :(得分:0)

我可以看到为什么你的隐含不会解决,所以我试着解释它为什么不满足范围规则。

但我不清楚你的意图是什么,所以我无法建议解决方法。

一步一步:

  1. 要满足此表达式implicitly[TC[sub2.F]],编译器将搜索词法(周围)范围,然后搜索类型TCsub2.F.type的同伴(如果有)(即,类型对象F嵌套在Outer)。
  2. 在词汇范围内,只有TC[Option],与sub2.F.type的类型不同。
  3. 在随播广告范围中,TC没有随播广告对象。 sub2.F不是一个类,它是一个对象,所以它不能有一个伴侣对象。
  4. 如果您想在F中引用特征Outer,则需要类型投影运算符#,例如sub2#F