简体   繁体   English

Scala:泛型类型的隐式证据

[英]Scala: Implicit evidence for generic types

Assume there are such two traits: 假设有两个特征:

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

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

And a function: 和一个功能:

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

Everything works so far. 到目前为止一切正常。 However, I was stuck when trying to make bar work recursively on collection types like Seq[T] (ie bar[Seq[T]](seq) recursively calls bar[T] on seq 's elements). 但是,当尝试使bar在诸如Seq[T]集合类型上递归工作时,我陷入了困境(即bar[Seq[T]](seq)seq的元素上递归调用bar[T] )。 I can't do implicit object CanFooSeq extends CanFoo[Seq[_]] since that would cause the type information of the elements to be lost. 我不能做implicit object CanFooSeq extends CanFoo[Seq[_]]因为那样会导致元素的类型信息丢失。 (I also tried to make another function def bar[T: CanFoo](seq: Seq[T]) = ... , but that didn't solve the problem either since Seq[T] still isn't being recognized as a Foo-able type.) (我也试图制作另一个函数def bar[T: CanFoo](seq: Seq[T]) = ... ,但这也没有解决问题,因为Seq[T]仍未被识别为Foo-able类型。)

Is there any way to solve this problem? 有什么办法解决这个问题?

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

(if you want to have it only in case you have CanFoo[T] , add the implicit parameter: implicit def CanFooSeq[T: CanFoo]: CanFoo[Seq[T]] = new CanFoo[Seq[T]] { def fooer = ... } ) if I understood the question correctly. (如果只想在拥有CanFoo[T]情况下拥有它,请添加隐式参数: implicit def CanFooSeq[T: CanFoo]: CanFoo[Seq[T]] = new CanFoo[Seq[T]] { def fooer = ... } )是否正确理解了这个问题。 Note it has to be a def , because objects and vals can't have type parameters, so a new one will be created on each call (which is very unlikely to matter for performance in practice). 请注意,它必须是def ,因为对象和val不能具有类型参数,因此将在每次调用时创建一个新参数(在实践中这对性能的影响很小)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM