【问题标题】:How can I hide my implicit method or disable `LabelledGeneric` for a specific sealed family? [duplicate]如何隐藏我的隐式方法或禁用特定密封系列的“LabelledGeneric”? [复制]
【发布时间】:2015-04-21 19:18:30
【问题描述】:

我必须使用第三方特征,其设计如下:

trait Super[T]
trait Sub[T] extends Super[T]

并且我已经定义了以下方法来为任意密封族提供实例:

implicit def subFor[T, Repr](
  implicit
  gen: LabelledGeneric.Aux[T, Repr],
  sg: Lazy[JsonFormat[Repr]]
): Sub[T] = ???

但是在代码的其他地方,有人已经定义了

implicit def superFor[T]: Super[T] = ???

对于某些特定类型,例如Option 和其他一些人。

实际上,我想使用现有的实现而不是 使用我的subFor 通用实现。然而,因为我的 方法返回 Sub[T] 并且现有的实现返回 Super[T] 我看不到任何方法来定义我的实现 这样的方式,它被认为是较低的优先级。

如何阻止我的subFor 被特定类型调用? 有什么方法可以禁用LabelledGeneric 特定的 类型,或一些优先级降低机制,将停止 编译器永远不会寻找我的subFor,如果它已经看到了 Super[T]?

【问题讨论】:

  • 旧的ambiguous implicits trick 应该在这里工作。
  • @TravisBrown 太棒了!我应该使用规范的无形 Not[T] 吗?
  • 我不这么认为——存在类型不平等(以这种方式实现),但 IIRC 不是类型类否定。
  • 应该是Sub[T] extends Super[T]?

标签: scala shapeless


【解决方案1】:

如果在伴生对象中定义了隐式定义,则必须求助于基于碰撞的类型计算。但是对于“某些特定类型”,defs 通常不在类的伴随对象中(例如,不在 object Option 上)。在这种情况下,您可以利用隐式在给定名称空间中相互隐藏的事实。所以你可以

implicit def superFor[T]: SomeThrowawayType = ???

他们的superFor 将不再起作用。由于您更改了返回类型,因此它不会发生冲突或任何事情;它实际上已经消失了。然后,您可以创建自己的转发器,无论您想要显式调用其定义的优先级。

但是,这确实需要您在 他们之后导入您的东西(因此它会影响他们的)。如果这看起来过于繁琐而无法依赖,您将不得不进行类型计算。

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 2016-07-04
    • 2010-11-04
    • 1970-01-01
    • 2020-04-20
    • 2021-09-27
    • 1970-01-01
    相关资源
    最近更新 更多