确保隐式定义始终具有较高/较低优先级的一般方法

问题描述 投票:2回答:1

我有以下格式的类型类情况,有些复杂:

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的声明比该类型hasOtherTCS声明更具体。

是否存在general方式来确保隐式定义始终具有比其他定义更高/更低的优先级? (我的问题不是上面的特定代码。)

让我知道发布更完整的示例代码是否有帮助。

scala typeclass implicit
1个回答
3
投票

请参阅Why is this implicit ambiguity behaviour happening?和评论。

在这种情况下,引入特征LowPriorityTypeClass是没有意义的,因为无论如何隐式defaulthasOtherTC更具体。

没有一般方法。您可以使用类型类Notshapeless.Refuteimplicitbox.Not)或shapeless.LowPriorityimplicitbox.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] = ???
}
© www.soinside.com 2019 - 2024. All rights reserved.