[英]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.