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 不能有类型参数,所以每次调用都会创建一个新的(这在实践中对性能影响不大)。
假设有两个特征:
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 不能有类型参数,所以每次调用都会创建一个新的(这在实践中对性能影响不大)。