我有以下格式的类型类情况,有些复杂:
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
特性中,目的是降低优先级。但是,对于某些类型hasOtherTC
,仍然会与S
产生歧义,这显然是因为default
的声明比该类型hasOtherTC
的S
声明更具体。
是否存在general方式来确保隐式定义始终具有比其他定义更高/更低的优先级? (我的问题不是上面的特定代码。)
让我知道发布更完整的示例代码是否有帮助。
请参阅Why is this implicit ambiguity behaviour happening?和评论。
在这种情况下,引入特征LowPriorityTypeClass
是没有意义的,因为无论如何隐式default
比hasOtherTC
更具体。
没有一般方法。您可以使用类型类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] = ???
}