我如何定义隐式 class 可以同时拉皮条基础和派生 class

How do I define implicit class that can pimp both base and derived class

我如何定义隐式 class 可以对基础和派生 class 进行 pimp?

我想实施 class 来拉皮条 Flow and Source。我试过这个

implicit class FlowOpsMatExt[T, Mat](val flow: FlowOpsMat[T, Mat]) {
  def groupSortedByKey[K](keyForItem: T ⇒ K, maxBufferSize: Int): flow.Repr[Vector[T]]
}

但是调用 Source[] 的实例时,我得到了 FlowOpsMat,我不能再将其用作源。所以我试图欺骗它

implicit class FlowOpsMatExt[T, Mat, C <: FlowOpsMat[T, Mat]](val flow2: C)

但由于某种原因未能检测到类型。在显式调用中

new FlowOpsMatExt(source_instance)

我收到以下错误

Error:(106, 5) inferred type arguments [Nothing,Nothing,akka.stream.scaladsl.Source[akka.util.ByteString,akka.NotUsed]] do not conform to class FlowOpsMatExt's type parameter bounds [T,Mat,C <: akka.stream.scaladsl.FlowOpsMat[T,Mat]]
    new FlowOpsMatExt(src)

要重现的最小示例:https://gist.github.com/931a313546f14e809b705e86743dcdb0

如果我显式指定所有类型,它会编译 new FlowOpsMatExt[ByteString, NotUsed, Source[ByteString, NotUsed]](src) 但它会破坏使用隐式 class.

的好处

我错过了什么?

我能想到的最好办法是保持扩展函数的抽象实现 class 并从中实现两个隐式 classes

abstract class FlowOpsMatExt[T, Mat, C <: FlowOpsMat[T, Mat]] {
  protected val flow: C
}

implicit class FlowExt2[In, Out, Mat](val flow: Flow[In, Out, Mat]) extends FlowOpsMatExt[Out, Mat, Flow[In, Out, Mat]] {
}

implicit class SourceExt[T, Mat](val flow: Source[T, Mat]) extends FlowOpsMatExt[T, Mat, Source[T, Mat]] {
}

来自documentation

Advanced Scala users may wonder whether it is possible to write extension methods that enrich FlowOps to allow nicer syntax. The short answer is that Scala 2 does not support this in a fully generic fashion, the problem is that it is impossible to abstract over the kind of stream that is being extended because Source, Flow and SubFlow differ in the number and kind of their type parameters. While it would be possible to write an implicit class that enriches them generically, this class would require explicit instantiation with all type parameters due to SI-2712. For a partial workaround that unifies extensions to Source and Flow see this sketch by R. Kuhn.

...

It is interesting to note that a simplified form of this problem has found its way into the dotty test suite. Dotty is the development version of Scala on its way to Scala 3.