Scala:泛型类型的隐式证据

Scala: Implicit evidence for generic types

假设有两个特征:

trait Fooer[-T] {
  def foo(x: T): Unit
}

trait CanFoo[-T] {
  def fooer: Fooer[T]
}

还有一个函数:

def bar[T: CanFoo](x: T) = {
  implicitly[CanFoo[T]].fooer.foo(x)
}

到目前为止一切正常。然而,当我试图让 bar 递归地处理像 Seq[T] 这样的集合类型(即 bar[Seq[T]](seq)seq 的元素上递归调用 bar[T] 时,我被卡住了。我不能做 implicit object CanFooSeq extends CanFoo[Seq[_]] 因为那会导致元素的类型信息丢失。 (我还尝试创建另一个函数 def bar[T: CanFoo](seq: Seq[T]) = ...,但这也没有解决问题,因为 Seq[T] 仍然没有被识别为 Foo-able 类型。)

有什么办法可以解决这个问题吗?

implicit def CanFooSeq[T]: CanFoo[Seq[T]] = new CanFoo[Seq[T]] { def fooer = ... }

(如果你只想在有 CanFoo[T] 的情况下使用它,请添加隐式参数:implicit def CanFooSeq[T: CanFoo]: CanFoo[Seq[T]] = new CanFoo[Seq[T]] { def fooer = ... })如果我理解正确的话。请注意,它必须是 def,因为对象和 val 不能有类型参数,所以每次调用都会创建一个新的(这在实践中对性能影响不大)。