scala - 在 Scala 中消除隐式解析的歧义

标签 scala implicit

我希望在使 forgetBA 再次隐式化之后编译以下代码。

trait ImplicitExample {
  trait AA[T]
  trait AB[T] extends AA[T]
  trait BA[T] extends AA[T]
  trait BB[T] extends AB[T] with BA[T]

  object AA {
    implicit def forgetAB[T: AB]: AA[T] = implicitly[AA[T]]
    /*implicit*/ def forgetBA[T: BA]: AA[T] = implicitly[AA[T]]
  }

  object AB {
    implicit def forgetBB[T: BB]: AB[T] = implicitly[AB[T]]
  }
  object BA {
    implicit def forgetBB[T: BB]: BA[T] = implicitly[BA[T]]
  }
  object BB {
    implicit object BBInt extends BB[Int]
  }

  val AAInt = implicitly[AA[Int]]
}

我知道这会导致不明确的隐式解析问题,所以我正在寻找一种方法来表明对一个隐式解析的偏好。

我听说以某种方式插入中间特征可能会有所帮助,但我似乎找不到解释。

最佳答案

通常的技巧是这样写:

trait LowPriorityAAInstances {
  implicit def forgetAB[T: AB]: AA[T] = implicitly[AA[T]]
}

object AA extends LowPriorityAAInstances {
  implicit def forgetBA[T: BA]: AA[T] = implicitly[AA[T]]
}

这将在为 T 寻找 AA 实例时给予 forgetBA 优先级,其中有一个 BA(即使周围有 AB 的实例,仍然在编译)。

命名完全是约定俗成的问题,但最好用它来表明您只是以这种方式分解 AA 的定义以适应隐式搜索机制。

关于scala - 在 Scala 中消除隐式解析的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22650832/

相关文章:

scala - Http4s解码器如何自定义无效字段的错误消息

scala - 找不到元素类型 T 的类 list

scala - 为 Object 的上下文边界提供隐式证据

scala - 如何询问 Scala 是否存在所有类型参数实例化的证据?

c++ - 什么时候加载 DLL : Implicit Linking VS Explicit Linking

scala - 无法解析具有此类签名的引用 StructField

function - "Side-effecting lexical closure"vs Scala 中的函数

在方法调用后定义隐式 val 时,Scala 隐式参数为 null

c++ - 为什么我的隐式转换函数不起作用?

scala - 使用 Slick 3 的带有可选 where 子句的动态查询