确保隐式定义始终具有 higher/lower 优先级的一般方法

General way of ensuring implicit definition always has higher/lower priority

我的类型类情况有点复杂,格式如下:

sealed trait TypeClass[S <: MyType] {
  type Out <: MyType
}

sealed trait LowPriorityTypeClass {
  // Case: OtherTypeClass is NOT defined for the input type S.
  // The output type is the same as the input type.
  implicit def default[S <: MyType]: TypeClass.Aux[S, S] = ???
}

object TypeClass extends LowPriorityTypeClass {
  type Aux[S <: MyType, O <: MyType] = TypeClass[S] { type Out = O }

  // Case: OtherTypeClass is defined for the input type S.
  // The output type is the same as in the OtherTypeClass definition.
  implicit def hasOtherTC[S <: MyType, O <: MyType](
    implicit otherTC: OtherTypeClass.Aux[S, O],
  ): TypeClass.Aux[S, O] = ???
}

default 定义放在 LowPriorityTypeClass 特性中,目的是降低优先级。但是,对于某些类型 ShasOtherTC 的歧义仍然发生,显然是因为 default 的声明比 hasOtherTC 类型 S 的声明更具体].

是否有通用方法来确保隐式定义总是比其他定义具有higher/lower优先级? (我的问题不是针对上面的具体代码。)

如果发布更完整的示例代码会有帮助,请告诉我。

请参阅 ,包括评论。

在这种情况下引入特征 LowPriorityTypeClass 没有任何意义,因为无论如何隐式 defaulthasOtherTC.

更具体

没有通用的方法。您可以使用类型 类 Not (shapeless.Refute, implicitbox.Not) 或 shapeless.LowPriority, implicitbox.Priority 或库 https://github.com/milessabin/export-hook.

object TypeClass {
  type Aux[S <: MyType, O <: MyType] = TypeClass[S] {type Out = O}

  implicit def hasOtherTC[S <: MyType, O <: MyType](implicit
                                                    otherTC: OtherTypeClass.Aux[S, O]
                                                   ): TypeClass.Aux[S, O] = ???

  implicit def default[S <: MyType](implicit 
                                    noOtherTC: Refute[OtherTypeClass[S]]
                                   ): TypeClass.Aux[S, S] = ???
}