【问题标题】:Finding implicit values in the companion object of a nested type在嵌套类型的伴随对象中查找隐式值
【发布时间】:2016-02-27 05:10:59
【问题描述】:

我有一个特征 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
            ^

【问题讨论】:

    标签: scala typeclass implicit


    【解决方案1】:

    我知道为什么你的隐式不能解决,所以我会试着解释为什么它不满足范围规则。

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

    一步一步:

    1. 为了满足这个表达式implicitly[TC[sub2.F]],编译器将搜索词法(周围)范围,然后搜索TCsub2.F.type类型的同伴(如果有的话)(即对象的类型F嵌套在Outer)。
    2. 在词法范围内只有TC[Option],它与sub2.F.type 的类型不同。
    3. 在伴随范围内,TC 没有伴随对象。 sub2.F 不是一个类,它是一个对象,所以它不能有一个伴生对象。

    如果您要在Outer 中引用特征F,则需要类型投影 运算符#,例如sub2#F

    【讨论】:

    • 我不完全理解你的回答。它是否也解释了为什么implicitly[TC[sub.F]] 编译?
    • 事实上,我现在明白我的回答是错误的。我错误地认为在表达式TC[sub.F]F 中指的是对象F。但实际上,scala 微妙的重载语法意味着在类型上下文中,sub.F 指的是 trait F 的类型。
    猜你喜欢
    • 1970-01-01
    • 2016-08-24
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 2014-02-03
    • 2014-10-24
    • 1970-01-01
    相关资源
    最近更新 更多